Kali下使用libheap

Kali下使用libheap

在github上,可以libheap用来帮助调试堆溢出。链接见:https://github.com/cloudburst/libheap 但是最后一次更新在一年前了,我直接拿着在Kali 2.0上使用时,会出错,比如:

我就对其进行了修改,保证可以在Kali 2.0下完美使用,32位和64位都可以使用。我的系统版本:

以后碰见其它Linux发行版,都可以对其修改。在不同的发行版之间,在malloc_state和malloc_par结构体中,稍微有些区别,只需要下载相应的glibc源码,根据源码对libheap进行修改就可以了。在Kali 64位下,int是4字节,long是8字节,size_t是8字节。修改后的libheap见:

   1 from __future__ import print_function
   2 #modify by wah for kali 2.0
   3 try:
   4     import gdb
   5 except ImportError:
   6     print("Not running inside of GDB, exiting...")
   7     exit()
   8
   9 import sys
  10 import struct
  11 from os import uname
  12
  13 # bash color support
  14 color_support = True
  15 if color_support:
  16     c_red      = "\033[31m"
  17     c_red_b    = "\033[01;31m"
  18     c_green    = "\033[32m"
  19     c_green_b  = "\033[01;32m"
  20     c_yellow   = "\033[33m"
  21     c_yellow_b = "\033[01;33m"
  22     c_blue     = "\033[34m"
  23     c_blue_b   = "\033[01;34m"
  24     c_purple   = "\033[35m"
  25     c_purple_b = "\033[01;35m"
  26     c_teal     = "\033[36m"
  27     c_teal_b   = "\033[01;36m"
  28     c_none     = "\033[0m"
  29 else:
  30     c_red      = ""
  31     c_red_b    = ""
  32     c_green    = ""
  33     c_green_b  = ""
  34     c_yellow   = ""
  35     c_yellow_b = ""
  36     c_blue     = ""
  37     c_blue_b   = ""
  38     c_purple   = ""
  39     c_purple_b = ""
  40     c_teal     = ""
  41     c_teal_b   = ""
  42     c_none     = ""
  43 c_error  = c_red
  44 c_title  = c_green_b
  45 c_header = c_yellow_b
  46 c_value  = c_blue_b
  47
  48 ################################################################################
  49 # MALLOC CONSTANTS AND MACROS
  50 ################################################################################
  51
  52 _machine = uname()[4]
  53 if _machine == "x86_64":
  54     SIZE_SZ = 8
  55 elif _machine in ("i386", "i686"):
  56     SIZE_SZ = 4
  57
  58 MIN_CHUNK_SIZE    = 4 * SIZE_SZ
  59 MALLOC_ALIGNMENT  = 2 * SIZE_SZ
  60 MALLOC_ALIGN_MASK = MALLOC_ALIGNMENT - 1
  61 MINSIZE           = (MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK
  62
  63 def chunk2mem(p):
  64     "conversion from malloc header to user pointer"
  65     return (p.address + (2*SIZE_SZ))
  66
  67 def mem2chunk(mem):
  68     "conversion from user pointer to malloc header"
  69     return (mem - (2*SIZE_SZ))
  70
  71 def request2size(req):
  72     "pad request bytes into a usable size"
  73
  74     if (req + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE):
  75         return MINSIZE
  76     else:
  77         return (int(req + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
  78
  79 PREV_INUSE     = 1
  80 IS_MMAPPED     = 2
  81 NON_MAIN_ARENA = 4
  82 SIZE_BITS      = (PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA)
  83
  84 def prev_inuse(p):
  85     "extract inuse bit of previous chunk"
  86     return (p.size & PREV_INUSE)
  87
  88 def chunk_is_mmapped(p):
  89     "check for mmap()‘ed chunk"
  90     return (p.size & IS_MMAPPED)
  91
  92 def chunk_non_main_arena(p):
  93     "check for chunk from non-main arena"
  94     return (p.size & NON_MAIN_ARENA)
  95
  96 def chunksize(p):
  97     "Get size, ignoring use bits"
  98     return (p.size & ~SIZE_BITS)
  99
 100 def next_chunk(p):
 101     "Ptr to next physical malloc_chunk."
 102     return (p.address + (p.size & ~SIZE_BITS))
 103
 104 def prev_chunk(p):
 105     "Ptr to previous physical malloc_chunk"
 106     return (p.address - p.prev_size)
 107
 108 def chunk_at_offset(p, s):
 109     "Treat space at ptr + offset as a chunk"
 110     return malloc_chunk(p.address + s, inuse=False)
 111
 112 def inuse(p):
 113     "extract p‘s inuse bit"
 114     return (malloc_chunk(p.address +  115             (p.size & ~SIZE_BITS), inuse=False).size & PREV_INUSE)
 116
 117 def set_inuse(p):
 118     "set chunk as being inuse without otherwise disturbing"
 119     chunk = malloc_chunk((p.address + (p.size & ~SIZE_BITS)), inuse=False)
 120     chunk.size |= PREV_INUSE
 121     chunk.write()
 122
 123 def clear_inuse(p):
 124     "clear chunk as being inuse without otherwise disturbing"
 125     chunk = malloc_chunk((p.address + (p.size & ~SIZE_BITS)), inuse=False)
 126     chunk.size &= ~PREV_INUSE
 127     chunk.write()
 128
 129 def inuse_bit_at_offset(p, s):
 130     "check inuse bits in known places"
 131     return (malloc_chunk((p.address + s), inuse=False).size & PREV_INUSE)
 132
 133 def set_inuse_bit_at_offset(p, s):
 134     "set inuse bits in known places"
 135     chunk = malloc_chunk((p.address + s), inuse=False)
 136     chunk.size |= PREV_INUSE
 137     chunk.write()
 138
 139 def clear_inuse_bit_at_offset(p, s):
 140     "clear inuse bits in known places"
 141     chunk = malloc_chunk((p.address + s), inuse=False)
 142     chunk.size &= ~PREV_INUSE
 143     chunk.write()
 144
 145 def bin_at(m, i):
 146     "addressing -- note that bin_at(0) does not exist"
 147     if SIZE_SZ == 4:
 148         offsetof_fd = 0x8
 149         return (gdb.parse_and_eval("&main_arena.bins[%d]" %  150             ((i -1) * 2)).cast(gdb.lookup_type(‘unsigned int‘)) - offsetof_fd)
 151     elif SIZE_SZ == 8:
 152         offsetof_fd = 0x10
 153         return (gdb.parse_and_eval("&main_arena.bins[%d]" %  154             ((i -1) * 2)).cast(gdb.lookup_type(‘unsigned long‘)) - offsetof_fd)
 155
 156 def next_bin(b):
 157     return (b + 1)
 158
 159 def first(b):
 160     return b.fd
 161
 162 def last(b):
 163     return b.bk
 164
 165 NBINS          = 128
 166 NSMALLBINS     = 64
 167 SMALLBIN_WIDTH = MALLOC_ALIGNMENT
 168 MIN_LARGE_SIZE = (NSMALLBINS * SMALLBIN_WIDTH)
 169
 170 def in_smallbin_range(sz):
 171     "check if size is in smallbin range"
 172     return (sz < MIN_LARGE_SIZE)
 173
 174 def smallbin_index(sz):
 175     "return the smallbin index"
 176
 177     if SMALLBIN_WIDTH == 16:
 178         return (sz >> 4)
 179     else:
 180         return (sz >> 3)
 181
 182 def largebin_index_32(sz):
 183     "return the 32bit largebin index"
 184
 185     if (sz >> 6) <= 38:
 186         return (56 + (sz >> 6))
 187     elif (sz >> 9) <= 20:
 188         return (91 + (sz >> 9))
 189     elif (sz >> 12) <= 10:
 190         return (110 + (sz >> 12))
 191     elif (sz >> 15) <= 4:
 192         return (119 + (sz >> 15))
 193     elif (sz >> 18) <= 2:
 194         return (124 + (sz >> 18))
 195     else:
 196         return 126
 197
 198 def largebin_index_64(sz):
 199     "return the 64bit largebin index"
 200
 201     if (sz >> 6) <= 48:
 202         return (48 + (sz >> 6))
 203     elif (sz >> 9) <= 20:
 204         return (91 + (sz >> 9))
 205     elif (sz >> 12) <= 10:
 206         return (110 + (sz >> 12))
 207     elif (sz >> 15) <= 4:
 208         return (119 + (sz >> 15))
 209     elif (sz >> 18) <= 2:
 210         return (124 + (sz >> 18))
 211     else:
 212         return 126
 213
 214 def largebin_index(sz):
 215     "return the largebin index"
 216
 217     if SIZE_SZ == 8:
 218         return largebin_index_64(sz)
 219     else:
 220         return largebin_index_32(sz)
 221
 222 def bin_index(sz):
 223     "return the bin index"
 224
 225     if in_smallbin_range(sz):
 226         return smallbin_index(sz)
 227     else:
 228         return largebin_index(sz)
 229
 230 BINMAPSHIFT = 5
 231 BITSPERMAP  = 1 << BINMAPSHIFT
 232 BINMAPSIZE  = (NBINS / BITSPERMAP)
 233
 234 def fastbin(ar_ptr, idx):
 235     return ar_ptr.fastbinsY[idx]
 236
 237 def fastbin_index(sz):
 238     "offset 2 to use otherwise unindexable first 2 bins"
 239     if SIZE_SZ == 8:
 240         return ((sz >> 4) - 2)
 241     else:
 242         return ((sz >> 3) - 2)
 243
 244 MAX_FAST_SIZE = (80 * SIZE_SZ / 4)
 245 NFASTBINS     = (fastbin_index(request2size(MAX_FAST_SIZE)) + 1)
 246
 247 FASTCHUNKS_BIT = 0x1
 248
 249 def have_fastchunks(M):
 250     return ((M.flags & FASTCHUNKS_BIT) == 0)
 251
 252 def clear_fastchunks(M, inferior=None):
 253     if inferior == None:
 254         inferior = get_inferior()
 255
 256     M.flags |= FASTCHUNKS_BIT
 257     inferior.write_memory(M.address, struct.pack("<I", M.flags))
 258
 259 def set_fastchunks(M, inferior=None):
 260     if inferior == None:
 261         inferior = get_inferior()
 262
 263     M.flags &= ~FASTCHUNKS_BIT
 264     inferior.write_memory(M.address, struct.pack("<I", M.flags))
 265
 266 NONCONTIGUOUS_BIT = 0x2
 267
 268 def contiguous(M):
 269     return ((M.flags & NONCONTIGUOUS_BIT) == 0)
 270
 271 def noncontiguous(M):
 272     return ((M.flags & NONCONTIGUOUS_BIT) != 0)
 273
 274 def set_noncontiguous(M, inferior=None):
 275     if inferior == None:
 276         inferior = get_inferior()
 277
 278     M.flags |= NONCONTIGUOUS_BIT
 279     inferior.write_memory(M.address, struct.pack("<I", M.flags))
 280
 281 def set_contiguous(M, inferior=None):
 282     if inferior == None:
 283         inferior = get_inferior()
 284
 285     M.flags &= ~NONCONTIGUOUS_BIT
 286     inferior.write_memory(M.address, struct.pack("<I", M.flags))
 287
 288 def get_max_fast():
 289     return gdb.parse_and_eval("global_max_fast")
 290
 291 def mutex_lock(ar_ptr, inferior=None):
 292     if inferior == None:
 293         inferior = get_inferior()
 294
 295     ar_ptr.mutex = 1
 296     inferior.write_memory(ar_ptr.address, struct.pack("<I", ar_ptr.mutex))
 297
 298 def mutex_unlock(ar_ptr, inferior=None):
 299     if inferior == None:
 300         inferior = get_inferior()
 301
 302     ar_ptr.mutex = 0
 303     inferior.write_memory(ar_ptr.address, struct.pack("<I", ar_ptr.mutex))
 304
 305 def get_inferior():
 306     try:
 307         if len(gdb.inferiors()) == 0:
 308             print(c_error + "No gdb inferior could be found." + c_none)
 309             return -1
 310         else:
 311             inferior = gdb.inferiors()[0]
 312             return inferior
 313     except AttributeError:
 314         print(c_error + "This gdb‘s python support is too old." + c_none)
 315         exit()
 316
 317
 318 ################################################################################
 319 class malloc_chunk:
 320     "python representation of a struct malloc_chunk"
 321
 322     def __init__(self,addr=None,mem=None,size=None,inferior=None,inuse=False,read_data=True):
 323         self.prev_size   = 0
 324         self.size        = 0
 325         self.data        = None
 326         self.fd          = None
 327         self.bk          = None
 328         self.fd_nextsize = None
 329         self.bk_nextsize = None
 330
 331         if addr == None or addr == 0:
 332             if mem == None:
 333                 sys.stdout.write(c_error)
 334                 print("Please specify a valid struct malloc_chunk address.", end=‘ ‘)
 335                 sys.stdout.write(c_none)
 336                 return None
 337
 338             self.address = None
 339         else:
 340             self.address = addr
 341
 342         if inferior == None and mem == None:
 343             inferior = get_inferior()
 344             if inferior == -1:
 345                 return None
 346
 347         if mem == None:
 348             # a string of raw memory was not provided
 349             try:
 350                 if SIZE_SZ == 4:
 351                     mem = inferior.read_memory(addr, 0x8)
 352                 elif SIZE_SZ == 8:
 353                     mem = inferior.read_memory(addr, 0x10)
 354             except TypeError:
 355                 print(c_error + "Invalid address specified." + c_none)
 356                 return None
 357             except RuntimeError:
 358                 print(c_error + "Could not read address 0x%x" % addr + c_none)
 359                 return None
 360         else:
 361             # a string of raw memory was provided
 362             if inuse:
 363                 if (len(mem)!=0x8) and (len(mem)<0x10):
 364                     sys.stdout.write(c_error)
 365                     print("Insufficient memory provided for a malloc_chunk.", end=‘ ‘)
 366                     sys.stdout.write(c_none)
 367                     return None
 368                 if len(mem)==0x8 or len(mem)==0x10:
 369                     #header only provided
 370                     read_data = False
 371             else:
 372                 if (len(mem)!=0x18) and (len(mem)<0x30):
 373                     sys.stdout.write(c_error)
 374                     print("Insufficient memory provided for a free chunk.", end=‘ ‘)
 375                     sys.stdout.write(c_none)
 376                     return None
 377
 378         if SIZE_SZ == 4:
 379             (self.prev_size,
 380             self.size) = struct.unpack_from("<II", mem, 0x0)
 381         elif SIZE_SZ == 8:
 382             (self.prev_size,
 383             self.size) = struct.unpack_from("<QQ", mem, 0x0)
 384
 385         if size == None:
 386             real_size = (self.size & ~SIZE_BITS)
 387         else:
 388             #a size was provided (for a malformed chunk with an invalid size)
 389             real_size = size & ~SIZE_BITS
 390
 391         if inuse:
 392             if read_data:
 393                 if self.address != None:
 394                     # a string of raw memory was not provided
 395                     try:
 396                         mem = inferior.read_memory(addr, real_size + SIZE_SZ)
 397                     except TypeError:
 398                         print(c_error + "Invalid address specified." + c_none)
 399                         return None
 400                     except RuntimeError:
 401                         print(c_error + "Could not read address 0x%x" % addr  402                                 + c_none)
 403                         return None
 404
 405                 real_size = (real_size - SIZE_SZ) / SIZE_SZ
 406                 if SIZE_SZ == 4:
 407                     self.data = struct.unpack_from("<%dI" % real_size, mem, 0x8)
 408                 elif SIZE_SZ == 8:
 409                     self.data = struct.unpack_from("<%dQ" %real_size, mem, 0x10)
 410
 411         if not inuse:
 412             if self.address != None:
 413                 # a string of raw memory was not provided
 414                 if inferior != None:
 415                     if SIZE_SZ == 4:
 416                         mem = inferior.read_memory(addr, 0x18)
 417                     elif SIZE_SZ == 8:
 418                         mem = inferior.read_memory(addr, 0x30)
 419
 420             if SIZE_SZ == 4:
 421                 (self.fd,          422                 self.bk,           423                 self.fd_nextsize,  424                 self.bk_nextsize) = struct.unpack_from("<IIII", mem, 0x8)
 425             elif SIZE_SZ == 8:
 426                 (self.fd,          427                 self.bk,           428                 self.fd_nextsize,  429                 self.bk_nextsize) = struct.unpack_from("<QQQQ", mem, 0x10)
 430
 431     def write(self, inferior=None):
 432         if self.fd == None and self.bk == None:
 433             inuse = True
 434         else:
 435             inuse = False
 436
 437         if inferior == None:
 438             inferior = get_inferior()
 439             if inferior == -1:
 440                 return None
 441
 442         if inuse:
 443             if SIZE_SZ == 4:
 444                 mem = struct.pack("<II", self.prev_size, self.size)
 445                 if self.data != None:
 446                     mem += struct.pack("<%dI" % len(self.data), *self.data)
 447             elif SIZE_SZ == 8:
 448                 mem = struct.pack("<QQ", self.prev_size, self.size)
 449                 if self.data != None:
 450                     mem += struct.pack("<%dQ" % len(self.data), *self.data)
 451         else:
 452             if SIZE_SZ == 4:
 453                 mem = struct.pack("<IIIIII", self.prev_size, self.size,  454                         self.fd, self.bk, self.fd_nextsize, self.bk_nextsize)
 455             elif SIZE_SZ == 8:
 456                 mem = struct.pack("<QQQQQQ", self.prev_size, self.size,  457                         self.fd, self.bk, self.fd_nextsize, self.bk_nextsize)
 458
 459         inferior.write_memory(self.address, mem)
 460
 461     def __str__(self):
 462         if self.prev_size == 0 and self.size == 0:
 463             return ""
 464         elif self.fd == None and self.bk == None:
 465             ret =  "%s%s%x%s%x%s" %                                466                     (c_title + "struct malloc_chunk {",            467                     c_none + "\nprev_size   = " + c_value + "0x",  468                     self.prev_size,                                469                     c_none + "\nsize        = " + c_value + "0x",  470                     self.size, c_none)
 471
 472             if self.data != None:
 473                 if SIZE_SZ == 4:
 474                     ret += "%s%s%r" %                                        475                             ("\ndata        = " + c_value + str(self.data),  476                             c_none + "\nraw         = " + c_value,           477                             struct.pack("<%dI"%len(self.data), *self.data))
 478                 elif SIZE_SZ == 8:
 479                     ret += "%s%s%r" %                                        480                             ("\ndata        = " + c_value + str(self.data),  481                             c_none + "\nraw         = " + c_value,           482                             struct.pack("<%dQ"%len(self.data), *self.data))
 483                 ret += c_none
 484
 485             return ret
 486         else:
 487             return "%s%s%x%s%x%s%lx%s%lx%s%lx%s%lx%s" %            488                     (c_title + "struct malloc_chunk {",            489                     c_none + "\nprev_size   = " + c_value + "0x",  490                     self.prev_size,                                491                     c_none + "\nsize        = " + c_value + "0x",  492                     self.size,                                     493                     c_none + "\nfd          = " + c_value + "0x",  494                     self.fd,                                       495                     c_none + "\nbk          = " + c_value + "0x",  496                     self.bk,                                       497                     c_none + "\nfd_nextsize = " + c_value + "0x",  498                     self.fd_nextsize,                              499                     c_none + "\nbk_nextsize = " + c_value + "0x",  500                     self.bk_nextsize, c_none)
 501
 502 ################################################################################
 503 class malloc_state:
 504     "python representation of a struct malloc_state"
 505
 506     def __init__(self, addr=None, mem=None, inferior=None):
 507         self.mutex          = 0
 508         self.flags          = 0
 509         self.fastbinsY      = 0
 510         self.top            = 0
 511         self.last_remainder = 0
 512         self.bins           = 0
 513         self.binmap         = 0
 514         self.next           = 0
 515     self.next_free      = 0
 516         self.system_mem     = 0
 517         self.max_system_mem = 0
 518
 519         if addr == None:
 520             if mem == None:
 521                 sys.stdout.write(c_error)
 522                 print("Please specify a struct malloc_state address.")
 523                 sys.stdout.write(c_none)
 524                 return None
 525
 526             self.address = None
 527         else:
 528             self.address = addr
 529
 530         if inferior == None and mem == None:
 531             inferior = get_inferior()
 532             if inferior == -1:
 533                 return None
 534
 535         if mem == None:
 536             # a string of raw memory was not provided
 537             try:
 538                 if SIZE_SZ == 4:
 539                     mem = inferior.read_memory(addr, 0x450)
 540                 elif SIZE_SZ == 8:
 541                     mem = inferior.read_memory(addr, 0x888)
 542             except TypeError:
 543                 print(c_error + "Invalid address specified." + c_none)
 544                 return None
 545             except RuntimeError:
 546                 print(c_error + "Could not read address 0x%x" % addr + c_none)
 547                 return None
 548
 549         if SIZE_SZ == 4:
 550             (self.mutex,          551             self.flags)          = struct.unpack_from("<II", mem, 0x0)
 552             self.fastbinsY       = struct.unpack_from("<10I", mem, 0x8)
 553             (self.top,            554             self.last_remainder) = struct.unpack_from("<II", mem, 0x30)
 555
 556             self.bins            = struct.unpack_from("<254I", mem, 0x38)
 557             self.binmap          = struct.unpack_from("<IIII", mem, 0x430)
 558             (self.next,           559         self.next_free,       560             self.system_mem,      561             self.max_system_mem) = struct.unpack_from("<IIII", mem, 0x440)
 562         elif SIZE_SZ == 8:
 563             (self.mutex,          564             self.flags)          = struct.unpack_from("<II", mem, 0x0)
 565             self.fastbinsY       = struct.unpack_from("<10Q", mem, 0x8)
 566             (self.top,            567             self.last_remainder) = struct.unpack_from("<QQ", mem, 0x58)
 568             self.bins            = struct.unpack_from("<254Q", mem, 0x68)
 569             self.binmap          = struct.unpack_from("<IIII", mem, 0x858)
 570             (self.next,           571         self.next_free,       572             self.system_mem,      573             self.max_system_mem) = struct.unpack_from("<QQQQ", mem, 0x868)
 574
 575     def write(self, inferior=None):
 576         if inferior == None:
 577             inferior = get_inferior()
 578             if inferior == -1:
 579                 return None
 580
 581         if SIZE_SZ == 4:
 582             mem = struct.pack("<275I", self.mutex, self.flags, self.fastbinsY,  583                     self.top, self.last_remainder, self.bins, self.binmap,  584                     self.next, self.system_mem, self.max_system_mem)
 585         elif SIZE_SZ == 8:
 586             mem = struct.pack("<II266QIIIIQQQ", self.mutex, self.flags,  587                     self.fastbinsY, self.top, self.last_remainder, self.bins,  588                     self.binmap, self.next, self.system_mem,  589                     self.max_system_mem)
 590
 591         inferior.write_memory(self.address, mem)
 592
 593     def __str__(self):
 594         return "%s%s%x%s%x%s%s%lx%s%lx%s%s%s%lx%s%lx%s%lx%s" %       595                 (c_title + "struct malloc_state {",                  596                 c_none + "\nmutex          = " + c_value + "0x",     597                 self.mutex,                                          598                 c_none + "\nflags          = " + c_value + "0x",     599                 self.flags,                                          600                 c_none + "\nfastbinsY      = " + c_value + "{...}",  601                 c_none + "\ntop            = " + c_value + "0x",     602                 self.top,                                            603                 c_none + "\nlast_remainder = " + c_value + "0x",     604                 self.last_remainder,                                 605                 c_none + "\nbins           = " + c_value + "{...}",  606                 c_none + "\nbinmap         = " + c_value + "{...}",  607                 c_none + "\nnext           = " + c_value + "0x",     608                 self.next,                                           609                 c_none + "\nsystem_mem     = " + c_value + "0x",     610                 self.system_mem,                                     611                 c_none + "\nmax_system_mem = " + c_value + "0x",     612                 self.max_system_mem, c_none)
 613
 614
 615 ################################################################################
 616 class malloc_par:
 617     "python representation of a struct malloc_par"
 618
 619     def __init__(self, addr=None, mem=None, inferior=None):
 620         self.trim_threshold   = 0
 621         self.top_pad          = 0
 622         self.mmap_threshold   = 0
 623     self.arena_test       = 0
 624     self.arena_max        = 0
 625         self.n_mmaps          = 0
 626         self.n_mmaps_max      = 0
 627         self.max_n_mmaps      = 0
 628         self.no_dyn_threshold = 0
 629         self.mmapped_mem      = 0
 630         self.max_mmapped_mem  = 0
 631         self.max_total_mem    = 0
 632         self.sbrk_base        = 0
 633
 634         if addr == None:
 635             if mem == None:
 636                 sys.stdout.write(c_error)
 637                 print("Please specify a struct malloc_par address.")
 638                 sys.stdout.write(c_none)
 639                 return None
 640
 641             self.address = None
 642         else:
 643             self.address = addr
 644
 645         if inferior == None and mem == None:
 646             inferior = get_inferior()
 647             if inferior == -1:
 648                 return None
 649
 650         if mem == None:
 651             # a string of raw memory was not provided
 652             try:
 653                 if SIZE_SZ == 4:
 654                     mem = inferior.read_memory(addr, 0x34)
 655                 elif SIZE_SZ == 8:
 656                     mem = inferior.read_memory(addr, 0x58)
 657             except TypeError:
 658                 print(c_error + "Invalid address specified." + c_none)
 659                 return None
 660             except RuntimeError:
 661                 print(c_error + "Could not read address 0x%x" % addr + c_none)
 662                 return None
 663
 664         if SIZE_SZ == 4:
 665             (self.trim_threshold,  666             self.top_pad,          667             self.mmap_threshold,   668         self.arena_test,       669         self.arena_max,        670             self.n_mmaps,          671             self.n_mmaps_max,      672             self.max_n_mmaps,      673             self.no_dyn_threshold, 674             self.mmapped_mem,      675             self.max_mmapped_mem,  676             self.max_total_mem,    677             self.sbrk_base)       = struct.unpack("<13I", mem)
 678         elif SIZE_SZ == 8:
 679             (self.trim_threshold,  680             self.top_pad,          681             self.mmap_threshold,   682         self.arena_test,       683         self.arena_max,        684             self.n_mmaps,          685             self.n_mmaps_max,      686             self.max_n_mmaps,      687             self.no_dyn_threshold, 688             self.mmapped_mem,      689             self.max_mmapped_mem,  690             self.max_total_mem,    691             self.sbrk_base)       = struct.unpack("<5Q4I4Q", mem)
 692
 693     def __str__(self):
 694         return "%s%s%lx%s%lx%s%lx%s%x%s%x%s%x%s%x%s%lx%s%lx%s%lx%s%lx%s" %  695                 (c_title + "struct malloc_par {",                   696                 c_none + "\ntrim_threshold   = " + c_value + "0x",  697                 self.trim_threshold,                                698                 c_none + "\ntop_pad          = " + c_value + "0x",  699                 self.top_pad,                                       700                 c_none + "\nmmap_threshold   = " + c_value + "0x",  701                 self.mmap_threshold,                                702                 c_none + "\nn_mmaps          = " + c_value + "0x",  703                 self.n_mmaps,                                       704                 c_none + "\nn_mmaps_max      = " + c_value + "0x",  705                 self.n_mmaps_max,                                   706                 c_none + "\nmax_n_mmaps      = " + c_value + "0x",  707                 self.max_n_mmaps,                                   708                 c_none + "\nno_dyn_threshold = " + c_value + "0x",  709                 self.no_dyn_threshold,                              710                 c_none + "\nmmapped_mem      = " + c_value + "0x",  711                 self.mmapped_mem,                                   712                 c_none + "\nmax_mmapped_mem  = " + c_value + "0x",  713                 self.max_mmapped_mem,                               714                 c_none + "\nmax_total_mem    = " + c_value + "0x",  715                 self.max_total_mem,                                 716                 c_none + "\nsbrk_base        = " + c_value + "0x",  717                 self.sbrk_base,                                     718                 c_none)
 719
 720
 721
 722 ################################################################################
 723 # ARENA CONSTANTS AND MACROS
 724 ################################################################################
 725
 726 HEAP_MIN_SIZE     = 32 * 1024
 727 HEAP_MAX_SIZE     = 1024 * 1024
 728
 729 def top(ar_ptr):
 730     return ar_ptr.top
 731
 732 def heap_for_ptr(ptr):
 733     "find the heap and corresponding arena for a given ptr"
 734     return (ptr & ~(HEAP_MAX_SIZE-1))
 735
 736
 737 ################################################################################
 738 # GDB PRETTY PRINTERS
 739 ################################################################################
 740
 741 class malloc_par_printer:
 742     "pretty print the malloc parameters (mp_)"
 743
 744     def __init__(self, val):
 745         self.val = val
 746
 747     def to_string(self):
 748         return "%s%s%lx%s%lx%s%lx%s%x%s%x%s%x%s%x%s%lx%s%lx%s%lx%s%lx%s" %  749                 (c_title + "struct malloc_par {",                   750                 c_none + "\ntrim_threshold   = " + c_value + "0x",  751                 self.val[‘trim_threshold‘],                         752                 c_none + "\ntop_pad          = " + c_value + "0x",  753                 self.val[‘top_pad‘],                                754                 c_none + "\nmmap_threshold   = " + c_value + "0x",  755                 self.val[‘mmap_threshold‘],                         756                 c_none + "\nn_mmaps          = " + c_value + "0x",  757                 self.val[‘n_mmaps‘],                                758                 c_none + "\nn_mmaps_max      = " + c_value + "0x",  759                 self.val[‘n_mmaps_max‘],                            760                 c_none + "\nmax_n_mmaps      = " + c_value + "0x",  761                 self.val[‘max_n_mmaps‘],                            762                 c_none + "\nno_dyn_threshold = " + c_value + "0x",  763                 self.val[‘no_dyn_threshold‘],                       764                 c_none + "\nmmapped_mem      = " + c_value + "0x",  765                 self.val[‘mmapped_mem‘],                            766                 c_none + "\nmax_mmapped_mem  = " + c_value + "0x",  767                 self.val[‘max_mmapped_mem‘],                        768                 c_none + "\nmax_total_mem    = " + c_value + "0x",  769                 self.val[‘max_total_mem‘],                          770                 c_none + "\nsbrk_base        = " + c_value + "0x",  771                 self.val[‘sbrk_base‘],                              772                 c_none)
 773
 774     def display_string(self):
 775         return "string"
 776
 777 ################################################################################
 778 class malloc_state_printer:
 779     "pretty print a struct malloc_state (ar_ptr)"
 780
 781     def __init__(self, val):
 782         self.val = val
 783
 784     def to_string(self):
 785         return "%s%s%x%s%x%s%s%lx%s%lx%s%s%s%lx%s%lx%s%lx%s" %       786                 (c_title + "struct malloc_state {",                  787                 c_none + "\nmutex          = " + c_value + "0x",     788                 self.val[‘mutex‘],                                   789                 c_none + "\nflags          = " + c_value + "0x",     790                 self.val[‘flags‘],                                   791                 c_none + "\nfastbinsY      = " + c_value + "{...}",  792                 c_none + "\ntop            = " + c_value + "0x",     793                 self.val[‘top‘],                                     794                 c_none + "\nlast_remainder = " + c_value + "0x",     795                 self.val[‘last_remainder‘],                          796                 c_none + "\nbins           = " + c_value + "{...}",  797                 c_none + "\nbinmap         = " + c_value + "{...}",  798                 c_none + "\nnext           = " + c_value + "0x",     799                 self.val[‘next‘],                                    800                 c_none + "\nsystem_mem     = " + c_value + "0x",     801                 self.val[‘system_mem‘],                              802                 c_none + "\nmax_system_mem = " + c_value + "0x",     803                 self.val[‘max_system_mem‘],                          804                 c_none)
 805
 806     def display_string(self):
 807         return "string"
 808
 809 ################################################################################
 810 class malloc_chunk_printer:
 811     "pretty print a struct malloc_chunk"
 812
 813     def __init__(self, val):
 814         self.val = val
 815
 816     def to_string(self):
 817         return "%s%s%x%s%x%s%lx%s%lx%s%lx%s%lx%s" %            818                 (c_title + "struct malloc_chunk {",            819                 c_none + "\nprev_size   = " + c_value + "0x",  820                 self.val[‘prev_size‘],                         821                 c_none + "\nsize        = " + c_value + "0x",  822                 self.val[‘size‘],                              823                 c_none + "\nfd          = " + c_value + "0x",  824                 self.val[‘fd‘],                                825                 c_none + "\nbk          = " + c_value + "0x",  826                 self.val[‘bk‘],                                827                 c_none + "\nfd_nextsize = " + c_value + "0x",  828                 self.val[‘fd_nextsize‘],                       829                 c_none + "\nbk_nextsize = " + c_value + "0x",  830                 self.val[‘bk_nextsize‘],                       831                 c_none)
 832
 833     def display_string(self):
 834         return "string"
 835
 836 ################################################################################
 837 class heap_info_printer:
 838     "pretty print a struct heap_info"
 839
 840     def __init__(self, val):
 841         self.val = val
 842
 843     def to_string(self):
 844         return "%s%s%lx%s%lx%s%lx%s%lx%s" %                      845                 (c_title + "struct heap_info {",                 846                 c_none + "\nar_ptr        = " + c_value + "0x",  847                 self.val[‘ar_ptr‘],                              848                 c_none + "\nprev          = " + c_value + "0x",  849                 self.val[‘prev‘],                                850                 c_none + "\nsize          = " + c_value + "0x",  851                 self.val[‘size‘],                                852                 c_none + "\nmprotect_size = " + c_value + "0x",  853                 self.val[‘mprotect_size‘],                       854                 c_none)
 855
 856     def display_string(self):
 857         return "string"
 858
 859 ################################################################################
 860 def pretty_print_heap_lookup(val):
 861     "Look-up and return a pretty-printer that can print val."
 862
 863     # Get the type.
 864     type = val.type
 865
 866     # If it points to a reference, get the reference.
 867     if type.code == gdb.TYPE_CODE_REF:
 868         type = type.target()
 869
 870     # Get the unqualified type, stripped of typedefs.
 871     type = type.unqualified().strip_typedefs()
 872
 873     # Get the type name.
 874     typename = type.tag
 875     if typename == None:
 876         return None
 877     elif typename == "malloc_par":
 878         return malloc_par_printer(val)
 879     elif typename == "malloc_state":
 880         return malloc_state_printer(val)
 881     elif typename == "malloc_chunk":
 882         return malloc_chunk_printer(val)
 883     elif typename == "_heap_info":
 884         return heap_info_printer(val)
 885     else:
 886         print(typename)
 887
 888     # Cannot find a pretty printer.  Return None.
 889     return None
 890
 891
 892 ################################################################################
 893 # GDB COMMANDS
 894 ################################################################################
 895
 896 class print_malloc_stats(gdb.Command):
 897     "print general malloc stats, adapted from malloc.c mSTATs()"
 898
 899     def __init__(self):
 900         super(print_malloc_stats, self).__init__("print_mstats",
 901                                         gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
 902
 903     def invoke(self, arg, from_tty):
 904         "Specify an optional arena addr: print_mstats main_arena=0x12345"
 905
 906         try:
 907             mp         = gdb.selected_frame().read_var(‘mp_‘)
 908
 909             if arg.find("main_arena") == -1:
 910                 main_arena = gdb.selected_frame().read_var(‘main_arena‘)
 911                 main_arena_address = main_arena.address
 912             else:
 913                 arg = arg.split()
 914                 for item in arg:
 915                     if item.find("main_arena") != -1:
 916                         if len(item) < 12:
 917                             sys.stdout.write(c_error)
 918                             print("Malformed main_arena parameter")
 919                             sys.stdout.write(c_none)
 920                             return
 921                         else:
 922                             main_arena_address = int(item[11:],16)
 923         except RuntimeError:
 924             sys.stdout.write(c_error)
 925             print("No frame is currently selected.")
 926             sys.stdout.write(c_none)
 927             return
 928         except ValueError:
 929             sys.stdout.write(c_error)
 930             print("Debug glibc was not found.")
 931             sys.stdout.write(c_none)
 932             return
 933
 934         if main_arena_address == 0:
 935             sys.stdout.write(c_error)
 936             print("Invalid main_arena address (0)")
 937             sys.stdout.write(c_none)
 938             return
 939
 940         in_use_b = mp[‘mmapped_mem‘]
 941         system_b = in_use_b
 942
 943         arena = 0
 944         while(1):
 945             ar_ptr = malloc_state(main_arena_address)
 946             mutex_lock(ar_ptr)
 947
 948             sys.stdout.write(c_title)
 949             print("=================================", end=‘ ‘)
 950             print("Malloc Stats =================================\n")
 951             sys.stdout.write(c_none)
 952
 953             # account for top
 954             avail = chunksize(malloc_chunk(top(ar_ptr), inuse=True,  955                     read_data=False))
 956             nblocks = 1
 957
 958             nfastblocks = 0
 959             fastavail = 0
 960
 961             # traverse fastbins
 962             for i in range(NFASTBINS):
 963                 p = fastbin(ar_ptr, i)
 964                 while p!=0:
 965                     p = malloc_chunk(p, inuse=False)
 966                     nfastblocks += 1
 967                     fastavail += chunksize(p)
 968                     p = p.fd
 969
 970             avail += fastavail
 971
 972             # traverse regular bins
 973             for i in range(1, NBINS):
 974                 b = bin_at(ar_ptr, i)
 975                 p = malloc_chunk(first(malloc_chunk(b,inuse=False)),inuse=False)
 976
 977                 while p.address != b:
 978                     nblocks += 1
 979                     avail += chunksize(p)
 980                     p = malloc_chunk(first(p), inuse=False)
 981
 982             sys.stdout.write(c_header)
 983             print("Arena %d:" % arena)
 984             sys.stdout.write(c_none)
 985             print(c_none + "system bytes     = " +  986                     c_value + "0x%x" % ar_ptr.system_mem)
 987             print(c_none + "in use bytes     = " +  988                     c_value + "0x%x\n" % (ar_ptr.system_mem - avail))
 989
 990             system_b += ar_ptr.system_mem
 991             in_use_b += (ar_ptr.system_mem - avail)
 992
 993             mutex_unlock(ar_ptr)
 994             if ar_ptr.next == main_arena_address:
 995                 break
 996             else:
 997                 ar_ptr = malloc_state(ar_ptr.next)
 998                 arena += 1
 999
1000         print(c_header + "Total (including mmap):")
1001         print(c_none + "system bytes     = " + c_value + "0x%x" % system_b)
1002         print(c_none + "in use bytes     = " + c_value + "0x%x" % in_use_b)
1003         print(c_none + "max system bytes = " + 1004                 c_value + "0x%x" % mp[‘max_total_mem‘])
1005         print(c_none + "max mmap regions = " + 1006                 c_value + "0x%x" % mp[‘max_n_mmaps‘])
1007         print(c_none + "max mmap bytes   = " + 1008                 c_value + "0x%lx" % mp[‘max_mmapped_mem‘] + c_none)
1009
1010
1011 ################################################################################
1012 class heap(gdb.Command):
1013     "print a comprehensive view of the heap"
1014
1015     def __init__(self):
1016         super(heap, self).__init__("heap", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
1017
1018     def invoke(self, arg, from_tty):
1019         "Usage can be obtained via heap -h"
1020
1021         inferior = get_inferior()
1022         if inferior == -1:
1023             return
1024
1025         if arg.find("-h") != -1:
1026             print(c_title + "==============================", end=‘ ‘)
1027             print("Heap Dump Help ==================================\n" + c_none)
1028
1029             print(c_title + "Options:\n" + c_none)
1030             print(c_header + "  -a 0x1234" + c_none 1031                     + "\tSpecify an arena address")
1032             print(c_header + "  -b" + c_none + 1033                     "\t\tPrint compact bin listing (only free chunks)")
1034             print(c_header + "  -c" + c_none + 1035                     "\t\tPrint compact arena listing (all chunks)")
1036             print(c_header + "  -f [#]" + c_none + 1037                     "\tPrint all fast bins, or only a single fast bin")
1038             print(c_header + "  -l" + c_none + 1039                     "\t\tPrint a flat listing of all chunks in an arena")
1040             print(c_header + "  -s [#]" + c_none + 1041                     "\tPrint all small bins, or only a single small bin\n")
1042             return
1043
1044         a_found = f_found = s_found = p_fb = p_sb = p_b = p_l = p_c = 0
1045         for item in arg.split():
1046             if a_found == 1:
1047                 arena_address = int(item,16)
1048                 a_found = 0
1049                 continue
1050             if f_found == 1:
1051                 f_found = 0
1052                 try:
1053                     fb_number = int(item)
1054                 except:
1055                     pass
1056                 continue
1057             if s_found == 1:
1058                 s_found = 0
1059                 try:
1060                     sb_number = int(item)
1061                 except:
1062                     pass
1063                 continue
1064             if item.find("-a") != -1:
1065                 a_found = 1
1066             if item.find("f") != -1:
1067                 f_found = 1
1068                 fb_number = None
1069                 p_fb = 1
1070             if item.find("s") != -1:
1071                 s_found = 1
1072                 sb_number = None
1073                 p_sb = 1
1074             if item.find("b") != -1:
1075                 p_b = 1
1076             if item.find("l") != -1:
1077                 p_l = 1
1078             if item.find("c") != -1:
1079                 p_c = 1
1080
1081         if arg.find("-a") == -1:
1082             try:
1083                 main_arena = gdb.selected_frame().read_var(‘main_arena‘)
1084                 arena_address = main_arena.address
1085             except RuntimeError:
1086                 print(c_error + "No gdb frame is currently selected." + c_none)
1087                 return
1088             except ValueError:
1089                 print(c_error + "Debug glibc was not found, " 1090                     "guessing main_arena address via offset from libc." + c_none)
1091
1092                 #find heap by offset from end of libc in /proc
1093                 libc_end,heap_begin = read_proc_maps(inferior.pid)
1094
1095                 if SIZE_SZ == 4:
1096                     #__malloc_initialize_hook + 0x20
1097                     #offset seems to be +0x380 on debug glibc, +0x3a0 otherwise
1098                     arena_address = libc_end + 0x3a0
1099                 elif SIZE_SZ == 8:
1100                     #offset seems to be +0xe80 on debug glibc, +0xea0 otherwise
1101                     arena_address = libc_end + 0xea0
1102
1103                 if libc_end == -1:
1104                     print(c_error + "Invalid address read via /proc" + c_none)
1105                     return
1106
1107         if arena_address == 0:
1108             print(c_error + "Invalid arena address (0)" + c_none)
1109             return
1110         ar_ptr = malloc_state(arena_address)
1111
1112         if len(arg) == 0:
1113             if ar_ptr.next == 0:
1114                 print("%s%s %s 0x%x) %s" % (c_error, 1115                         "ERROR: No arenas could be correctly guessed.", 1116                         "(Nothing was found at", ar_ptr.address, c_none))
1117                 return
1118
1119             print(c_title + "==================================", end=‘ ‘)
1120             print("Heap Dump ===================================\n" + c_none)
1121
1122             print(c_title + "Arena(s) found:" + c_none)
1123             try: #arena address obtained via read_var
1124                 print("\t arena @ 0x%x" % 1125                         ar_ptr.address.cast(gdb.lookup_type("unsigned long")))
1126             except: #arena address obtained via -a
1127                 print("\t arena @ 0x%x" % ar_ptr.address)
1128
1129             if ar_ptr.address != ar_ptr.next:
1130         print(‘no more than one arena‘)
1131                 #we have more than one arena
1132
1133                 curr_arena = malloc_state(ar_ptr.next)
1134                 while (ar_ptr.address != curr_arena.address):
1135                     print("\t arena @ 0x%x" % curr_arena.address)
1136                     curr_arena = malloc_state(curr_arena.next)
1137
1138                     if curr_arena.address == 0:
1139                         print(c_error + 1140                            "ERROR: No arenas could be correctly found." + c_none)
1141                         break #breaking infinite loop
1142
1143             print("")
1144             return
1145
1146         try:
1147             fb_base = ar_ptr.address.cast(gdb.lookup_type("unsigned long")) + 8
1148         except Exception, e:
1149         print(e)
1150             fb_base = ar_ptr.address + 8
1151         if SIZE_SZ == 4:
1152             try:
1153                 sb_base=ar_ptr.address.cast(gdb.lookup_type("unsigned long"))+56
1154             except:
1155                 sb_base = ar_ptr.address + 56
1156         elif SIZE_SZ == 8:
1157             try:
1158                 sb_base = ar_ptr.address.cast(gdb.lookup_type("unsigned long"))1159                         + 104
1160             except:
1161                 sb_base = ar_ptr.address + 104
1162
1163         try:
1164             mp_ = gdb.selected_frame().read_var(‘mp_‘)
1165             mp_address = mp_.address
1166         except RuntimeError:
1167             print(c_error + "No gdb frame is currently selected." + c_none)
1168             return
1169         except ValueError:
1170             print(c_error + "Debug glibc was not found, " 1171                    "guessing mp_ address via offset from main_arena." + c_none)
1172
1173             if SIZE_SZ == 4:
1174                 try:
1175                     mp_address = ar_ptr.address.cast(gdb.lookup_type(1176                                                     "unsigned long")) + 0x460
1177                 except:
1178                     mp_address = ar_ptr.address + 0x460
1179             elif SIZE_SZ == 8: #offset 0x880 untested on 64bit
1180                 try:
1181                     mp_address = ar_ptr.address.cast(gdb.lookup_type(1182                                                     "unsigned long")) + 0x880
1183                 except:
1184                     mp_address = ar_ptr.address + 0x460
1185         sbrk_base = malloc_par(mp_address).sbrk_base
1186
1187         if p_fb:
1188             print_fastbins(inferior, fb_base, fb_number)
1189             print("")
1190         if p_sb:
1191             print_smallbins(inferior, sb_base, sb_number)
1192             print("")
1193         if p_b:
1194             print_bins(inferior, fb_base, sb_base)
1195             print("")
1196         if p_l:
1197             print_flat_listing(ar_ptr, sbrk_base)
1198             print("")
1199         if p_c:
1200             print_compact_listing(ar_ptr, sbrk_base)
1201             print("")
1202
1203
1204 ############################################################################
1205 def read_proc_maps(pid):
1206     ‘‘‘
1207     Locate the stack of a process using /proc/pid/maps.
1208     Will not work on hardened machines (grsec).
1209     ‘‘‘
1210
1211     filename = ‘/proc/%d/maps‘ % pid
1212
1213     try:
1214         fd = open(filename)
1215     except IOError:
1216         print(c_error + "Unable to open %s" % filename + c_none)
1217         return -1,-1
1218
1219     found = libc_begin = libc_end = heap_begin = heap_end = 0
1220     for line in fd:
1221         if line.find("libc-") != -1:
1222             fields = line.split()
1223
1224             libc_begin,libc_end = fields[0].split(‘-‘)
1225             libc_begin = int(libc_begin,16)
1226             libc_end = int(libc_end,16)
1227         elif line.find("heap") != -1:
1228             fields = line.split()
1229
1230             heap_begin,heap_end= fields[0].split(‘-‘)
1231             heap_begin = int(heap_begin,16)
1232             heap_end = int(heap_end,16)
1233
1234     fd.close()
1235
1236     if libc_begin==0 or libc_end==0:
1237         print(c_error+"Unable to read libc address information via /proc"+c_none)
1238         return -1,-1
1239
1240     if heap_begin==0 or heap_end==0:
1241         print(c_error+"Unable to read heap address information via /proc"+c_none)
1242         return -1,-1
1243
1244     return libc_end,heap_begin
1245
1246
1247 ################################################################################
1248 def print_fastbins(inferior, fb_base, fb_num):
1249     "walk and print the fast bins"
1250
1251     print(c_title + "===================================", end=‘ ‘)
1252     print("Fastbins ===================================\n" + c_none)
1253
1254     for fb in range(0,NFASTBINS):
1255         if fb_num != None:
1256             fb = fb_num
1257
1258         offset = fb_base + fb*SIZE_SZ
1259         try:
1260             mem = inferior.read_memory(offset, SIZE_SZ)
1261             if SIZE_SZ == 4:
1262                 fd = struct.unpack("<I", mem)[0]
1263             elif SIZE_SZ == 8:
1264                 fd = struct.unpack("<Q", mem)[0]
1265         except RuntimeError:
1266             print(c_error + " ERROR: Invalid fb addr 0x%lx" % offset + c_none)
1267             return
1268
1269         print("%s%s%d%s%s0x%08lx%s%s%s0x%08lx%s%s" % 1270                 (c_header,"[ fb  ",fb," ] ",c_none,offset,1271                  " -> ",c_value,"[ ",fd," ]",c_none), end=‘ ‘)
1272
1273         if fd == 0: #fastbin is empty
1274             print("")
1275         else:
1276             fb_size = ((MIN_CHUNK_SIZE) +(MALLOC_ALIGNMENT)*fb)
1277             print("(%d)" % fb_size)
1278             chunk = malloc_chunk(fd, inuse=False)
1279             while chunk.fd != 0:
1280                 if chunk.fd is None:   # could not read memory section
1281                     break
1282                 print("%s%26s0x%08lx%s%s(%d)" % (c_value,"[ ",chunk.fd," ] ",c_none, fb_size))
1283                 chunk = malloc_chunk(chunk.fd, inuse=False)
1284
1285         if fb_num != None: #only print one fastbin
1286             return
1287
1288
1289 ################################################################################
1290 def print_smallbins(inferior, sb_base, sb_num):
1291     "walk and print the small bins"
1292
1293     print(c_title + "===================================", end=‘ ‘)
1294     print("Smallbins ==================================\n" + c_none)
1295
1296     for sb in range(2,NBINS+2,2):
1297         if sb_num != None and sb_num!=0:
1298             sb = sb_num*2
1299
1300         offset = sb_base + (sb-2)*SIZE_SZ
1301         try:
1302             mem = inferior.read_memory(offset, 2*SIZE_SZ)
1303             if SIZE_SZ == 4:
1304                 fd,bk = struct.unpack("<II", mem)
1305             elif SIZE_SZ == 8:
1306                 fd,bk = struct.unpack("<QQ", mem)
1307         except RuntimeError:
1308             print(c_error + " ERROR: Invalid sb addr 0x%lx" % offset + c_none)
1309             return
1310
1311         print("%s%s%02d%s%s0x%08lx%s%s%s0x%08lx%s0x%08lx%s%s" % 1312                             (c_header,"[ sb ",sb/2," ] ",c_none,offset, 1313                             " -> ",c_value,"[ ", fd, " | ", bk, " ] ",  1314                             c_none))
1315
1316         while (1):
1317             if fd == (offset-2*SIZE_SZ):
1318                 break
1319
1320             chunk = malloc_chunk(fd, inuse=False)
1321             print("%s%26s0x%08lx%s0x%08lx%s%s" % 1322                     (c_value,"[ ",chunk.fd," | ",chunk.bk," ] ",c_none), end=‘ ‘)
1323             print("(%d)" % chunksize(chunk))
1324
1325             fd = chunk.fd
1326
1327         if sb_num != None: #only print one smallbin
1328             return
1329
1330
1331 ################################################################################
1332 def print_bins(inferior, fb_base, sb_base):
1333     "walk and print the nonempty free bins, modified from jp"
1334
1335     print(c_title + "==================================", end=‘ ‘)
1336     print("Heap Dump ===================================\n" + c_none)
1337
1338     for fb in range(0,NFASTBINS):
1339         print_once = True
1340         p = malloc_chunk(fb_base-(2*SIZE_SZ)+fb*SIZE_SZ, inuse=False)
1341
1342         while (p.fd != 0):
1343             if p.fd is None:
1344                 break
1345
1346             if print_once:
1347                 print_once = False
1348                 print(c_header + "  fast bin %d   @ 0x%lx" % 1349                         (fb,p.fd) + c_none)
1350             print("    free chunk @ " + c_value + "0x%lx" % p.fd + c_none + 1351                   " - size" + c_value, end=‘ ‘)
1352             p = malloc_chunk(p.fd, inuse=False)
1353             print("0x%lx" % chunksize(p) + c_none)
1354
1355     for i in range(1, NBINS):
1356         print_once = True
1357         b = sb_base + i*2*SIZE_SZ - 4*SIZE_SZ
1358         p = malloc_chunk(first(malloc_chunk(b, inuse=False)), inuse=False)
1359
1360         while p.address != b:
1361             if print_once:
1362                 print_once = False
1363                 if i==1:
1364                     try:
1365                         print(c_header + "  unsorted bin @ 0x%lx" % 1366                           (b.cast(gdb.lookup_type("unsigned long")) 1367                           + 2*SIZE_SZ) + c_none)
1368                     except:
1369                         print(c_header + "  unsorted bin @ 0x%lx" % 1370                           (b + 2*SIZE_SZ) + c_none)
1371                 else:
1372                     try:
1373                         print(c_header + "  small bin %d @ 0x%lx" %  1374                          (i,b.cast(gdb.lookup_type("unsigned long")) 1375                          + 2*SIZE_SZ) + c_none)
1376                     except:
1377                         print(c_header + "  small bin %d @ 0x%lx" % 1378                          (i,b + 2*SIZE_SZ) + c_none)
1379
1380             print(c_none + "    free_chunk @ " + c_value 1381                   + "0x%lx " % p.address + c_none        1382                   + "- size " + c_value + "0x%lx" % chunksize(p) + c_none)
1383
1384             p = malloc_chunk(first(p), inuse=False)
1385
1386
1387 ################################################################################
1388 def print_flat_listing(ar_ptr, sbrk_base):
1389     "print a flat listing of an arena, modified from jp and arena.c"
1390
1391     print(c_title + "==================================", end=‘ ‘)
1392     print("Heap Dump ===================================\n" + c_none)
1393     print("%s%14s%17s%15s%s" % (c_header, "ADDR", "SIZE", "STATUS", c_none))
1394     print("sbrk_base " + c_value + "0x%lx" % sbrk_base)
1395
1396     p = malloc_chunk(sbrk_base, inuse=True, read_data=False)
1397
1398     while(1):
1399         print("%schunk     %s0x%-14lx 0x%-10lx%s" % 1400                 (c_none, c_value, p.address, chunksize(p), c_none), end=‘ ‘)
1401
1402         if p.address == top(ar_ptr):
1403             print("(top)")
1404             break
1405         elif p.size == (0|PREV_INUSE):
1406             print("(fence)")
1407             break
1408
1409         if inuse(p):
1410             print("%s" % "(inuse)")
1411         else:
1412             p = malloc_chunk(p.address, inuse=False)
1413             print("(F) FD %s0x%lx%s BK %s0x%lx%s" % 1414                     (c_value, p.fd, c_none,c_value,p.bk,c_none), end=‘ ‘)
1415
1416             if ((p.fd == ar_ptr.last_remainder) 1417             and (p.bk == ar_ptr.last_remainder) 1418             and (ar_ptr.last_remainder != 0)):
1419                 print("(LR)")
1420             elif ((p.fd == p.bk) & ~inuse(p)):
1421                 print("(LC)")
1422             else:
1423                 print("")
1424
1425         p = malloc_chunk(next_chunk(p), inuse=True, read_data=False)
1426
1427     print(c_none + "sbrk_end  " + c_value 1428             + "0x%lx" % (sbrk_base + ar_ptr.system_mem) + c_none)
1429
1430
1431 ################################################################################
1432 def print_compact_listing(ar_ptr, sbrk_base):
1433     "print a compact layout of the heap, modified from jp"
1434
1435     print(c_title + "==================================", end=‘ ‘)
1436     print("Heap Dump ===================================" + c_none)
1437     p = malloc_chunk(sbrk_base, inuse=True, read_data=False)
1438
1439     while(1):
1440         if p.address == top(ar_ptr):
1441             sys.stdout.write("|T|\n")
1442             break
1443
1444         if inuse(p):
1445             sys.stdout.write("|A|")
1446         else:
1447             p = malloc_chunk(p.address, inuse=False)
1448
1449             if ((p.fd == ar_ptr.last_remainder) 1450             and (p.bk == ar_ptr.last_remainder) 1451             and (ar_ptr.last_remainder != 0)):
1452                 sys.stdout.write("|L|")
1453             else:
1454                 sys.stdout.write("|%d|" % bin_index(p.size))
1455
1456         p = malloc_chunk(next_chunk(p), inuse=True, read_data=False)
1457
1458
1459 ################################################################################
1460 class print_bin_layout(gdb.Command):
1461     "dump the layout of a free bin"
1462
1463     def __init__(self):
1464         super(print_bin_layout, self).__init__("print_bin_layout",
1465                                         gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
1466
1467     def invoke(self, arg, from_tty):
1468         "Specify an optional arena addr: print_bin_layout main_arena=0x12345"
1469
1470         if len(arg) == 0:
1471             sys.stdout.write(c_error)
1472             print("Please specify the free bin to dump")
1473             sys.stdout.write(c_none)
1474             return
1475
1476         try:
1477             if arg.find("main_arena") == -1:
1478                 main_arena = gdb.selected_frame().read_var(‘main_arena‘)
1479                 main_arena_address = main_arena.address
1480             else:
1481                 arg = arg.split()
1482                 for item in arg:
1483                     if item.find("main_arena") != -1:
1484                         if len(item) < 12:
1485                             sys.stdout.write(c_error)
1486                             print("Malformed main_arena parameter")
1487                             sys.stdout.write(c_none)
1488                             return
1489                         else:
1490                             main_arena_address = int(item[11:],16)
1491         except RuntimeError:
1492             sys.stdout.write(c_error)
1493             print("No frame is currently selected.")
1494             sys.stdout.write(c_none)
1495             return
1496         except ValueError:
1497             sys.stdout.write(c_error)
1498             print("Debug glibc was not found.")
1499             sys.stdout.write(c_none)
1500             return
1501
1502         if main_arena_address == 0:
1503             sys.stdout.write(c_error)
1504             print("Invalid main_arena address (0)")
1505             sys.stdout.write(c_none)
1506             return
1507
1508         ar_ptr = malloc_state(main_arena_address)
1509         mutex_lock(ar_ptr)
1510
1511         sys.stdout.write(c_title)
1512         print("=================================", end=‘ ‘)
1513         print("Bin Layout ===================================\n")
1514         sys.stdout.write(c_none)
1515
1516         b = bin_at(ar_ptr, int(arg))
1517         p = malloc_chunk(first(malloc_chunk(b, inuse=False)), inuse=False)
1518         print_once = True
1519         print_str  = ""
1520         count      = 0
1521
1522         while p.address != b:
1523             if print_once:
1524                 print_once=False
1525                 print_str += "-->  " + c_value + "[bin %d]" % int(arg) + c_none
1526                 count += 1
1527
1528             print_str += "  <-->  " + c_value + "0x%lx" % p.address + c_none
1529             count += 1
1530             #print_str += "  <-->  0x%lx" % p.address
1531             p = malloc_chunk(first(p), inuse=False)
1532
1533         if len(print_str) != 0:
1534             print_str += "  <--"
1535             print(print_str)
1536             print("%s%s%s" % ("|"," " * (len(print_str) - 2 - count*12),"|"))
1537             print("%s" % ("-" * (len(print_str) - count*12)))
1538         else:
1539             print("Bin %d empty." % int(arg))
1540
1541         mutex_unlock(ar_ptr)
1542
1543
1544 ################################################################################
1545 class check_house_of_mind(gdb.Command):
1546     "print and help validate a house of mind layout"
1547
1548     def __init__(self):
1549         super(check_house_of_mind, self).__init__("check_house_of_mind",
1550                                         gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
1551
1552     def invoke(self, arg, from_tty):
1553         """
1554         Specify the house of mind method and chunk address (p=mem2chunk(mem)):
1555         check_house_of_mind method=unsortedbin p=0x12345678
1556         check_house_of_mind method=fastbin p=0x12345678
1557         """
1558
1559         if arg.find("method") == -1:
1560             print("Please specify the House of Mind method to use:")
1561             print("house_of_mind method={unsortedbin, fastbin}")
1562             return
1563         elif arg.find("p") == -1:
1564             print("Please specify the chunk address to use:")
1565             print("house_of_mind p=0x12345678")
1566             return
1567         else:
1568             arg = arg.split()
1569             for item in arg:
1570                 if item.find("method") != -1:
1571                     if len(item) < 8:
1572                         sys.stdout.write(c_error)
1573                         print("Malformed method parameter")
1574                         print("Please specify the House of Mind method to use:")
1575                         print("house_of_mind method={unsortedbin, fastbin}")
1576                         sys.stdout.write(c_none)
1577                         return
1578                     else:
1579                         method = item[7:]
1580                 if item.find("p") != -1:
1581                     if len(item) < 11:
1582                         sys.stdout.write(c_error)
1583                         print("Malformed chunk parameter")
1584                         print("Please specify the chunk address to use:")
1585                         print("house_of_mind p=0x12345678")
1586                         sys.stdout.write(c_none)
1587                         return
1588                     else:
1589                         p = int(item[2:],16)
1590
1591         sys.stdout.write(c_title)
1592         print("===============================", end=‘ ‘)
1593         print("House of Mind ==================================\n")
1594         sys.stdout.write(c_none)
1595
1596         if method.find("unsorted") != -1:
1597             self.unsorted_bin_method(p)
1598         elif method.find("fast") != -1:
1599             self.fast_bin_method(p)
1600
1601     def unsorted_bin_method(self, p):
1602         p = malloc_chunk(addr=p, inuse=True, read_data=False)
1603
1604         print(c_none + "Checking chunk p")
1605         print(c_none + " [*] p = " + c_value + "0x%x" % p.address + c_none)
1606
1607         if p.address < gdb.parse_and_eval("(unsigned int)%d" % -chunksize(p)):
1608             print(" [*] size does not wrap")
1609         else:
1610             print(c_error + " [_] ERROR: p > -size" + c_none)
1611             return
1612
1613         if chunksize(p) >= MINSIZE:
1614             print(" [*] size is > minimum chunk size")
1615         else:
1616             print(c_error + " [_] ERROR: chunksize(p) < MINSIZE" + c_none)
1617             return
1618
1619         if chunksize(p) > get_max_fast():
1620             print(" [*] size is not in fastbin range")
1621         else:
1622             print(c_error + " [_] ERROR: size is in fastbin range" + c_none)
1623             return
1624
1625         if not chunk_is_mmapped(p):
1626             print(" [*] is_mmapped bit is not set")
1627         else:
1628             print(c_error + " [_] ERROR: IS_MMAPPED bit is set" + c_none)
1629             return
1630
1631         if prev_inuse(p):
1632             print(" [*] prev_inuse bit is set")
1633         else:
1634             print(c_error + " [_] ERROR: PREV_INUSE bit is not set, this will", end=‘ ‘)
1635             print("trigger backward consolidation" + c_none)
1636
1637         if chunk_non_main_arena(p):
1638             print(" [*] non_main_arena flag is set")
1639         else:
1640             print(c_error + " [_] ERROR: p‘s non_main_arena flag is NOT set")
1641             return
1642
1643         print(c_none + "\nChecking struct heap_info")
1644         print(c_none + " [*] struct heap_info = " 1645                 + c_value + "0x%x" % heap_for_ptr(p.address))
1646
1647         inferior = get_inferior()
1648         if inferior == -1:
1649             return None
1650
1651         try:
1652             mem = inferior.read_memory(heap_for_ptr(p.address), SIZE_SZ)
1653             if SIZE_SZ == 4:
1654                 ar_ptr = struct.unpack("<I", mem)[0]
1655             elif SIZE_SZ == 8:
1656                 ar_ptr = struct.unpack("<Q", mem)[0]
1657         except RuntimeError:
1658             print(c_error + " [_] ERROR: Invalid heap_info address 0x%x" 1659                     % heap_for_ptr(p.address) + c_none)
1660             return
1661
1662         print(c_none + " [*] ar_ptr = " + c_value + "0x%x" % ar_ptr)
1663         print(c_none + "\nChecking struct malloc_state")
1664
1665         #test malloc_state address
1666         try:
1667             mutex = inferior.read_memory(ar_ptr, SIZE_SZ)
1668         except RuntimeError:
1669             print(c_error + " [_] ERROR: Invalid malloc_state address 0x%x" % 1670                     ar_ptr + c_none)
1671             return
1672
1673         av = malloc_state(ar_ptr)
1674
1675         if av.mutex == 0:
1676             print(c_none + " [*] av->mutex is zero")
1677         else:
1678             print(c_error + " [_] ERROR: av->mutex is not zero" + c_none)
1679             return
1680
1681         if p.address != av.top:
1682             print(c_none + " [*] p is not the top chunk")
1683         else:
1684             print(c_error + " [_] ERROR: p is the top chunk" + c_none)
1685             return
1686
1687         if noncontiguous(av):
1688             print(c_none + " [*] noncontiguous_bit is set")
1689         elif contiguous(av):
1690             print(c_error + 1691                 " [_] ERROR: noncontiguous_bit is NOT set in av->flags" + c_none)
1692             return
1693
1694         print(" [*] bck = &av->bins[0] = " + c_value + "0x%x" % (ar_ptr+0x38))
1695
1696         if SIZE_SZ == 4:
1697             print(c_none + " [*] fwd = bck->fd = *(&av->bins[0] + 8) =", end=‘ ‘)
1698         elif SIZE_SZ == 8:
1699             print(c_none + " [*] fwd = bck->fd = *(&av->bins[0] + 16) =", end=‘ ‘)
1700
1701         fwd = inferior.read_memory(ar_ptr + 0x38 + 2*SIZE_SZ, SIZE_SZ)
1702         if SIZE_SZ == 4:
1703             fwd = struct.unpack("<I", fwd)[0]
1704         elif SIZE_SZ == 8:
1705             fwd = struct.unpack("<Q", fwd)[0]
1706         print(c_value + "0x%x" % fwd)
1707
1708         if fwd != (ar_ptr+0x38):
1709             print(c_none + " [!] fwd->bk (0x%x) != bck (0x%x)" % 1710                     (fwd, ar_ptr+0x38) + c_error)
1711             print("     - ERROR: This will prevent this attack on glibc 2.11+", end=‘ ‘)
1712             print(c_none)
1713
1714         print(c_none + "\nChecking following chunks")
1715         nextchunk = chunk_at_offset(p, chunksize(p))
1716
1717         if prev_inuse(nextchunk):
1718             print(c_none + " [*] prev_inuse of the next chunk is set")
1719         else:
1720             print(c_error + " [_] PREV_INUSE bit of the next chunk is not set" 1721                     + c_none)
1722             return
1723
1724         if chunksize(nextchunk) > 2*SIZE_SZ:
1725             print(c_none + " [*] nextchunk size is > minimum size")
1726         else:
1727             print(c_error + " [_] ERROR: nextchunk size (%d) < %d" % 1728                     (chunksize(nextchunk), 2*SIZE_SZ) + c_none)
1729             return
1730
1731         if chunksize(nextchunk) < av.system_mem:
1732             print(c_none + " [*] nextchunk size is < av->system_mem")
1733         else:
1734             print(c_error + " [_] ERROR: nextchunk size (0x%x) >" % 1735                     chunksize(nextchunk), end=‘ ‘)
1736             print("av->system_mem (0x%x)" % av.system_mem + c_none)
1737             return
1738
1739         if nextchunk.address != av.top:
1740             print(c_none + " [*] nextchunk != av->top")
1741         else:
1742             print(c_error + " [_] ERROR: nextchunk is av->top (0x%x)" % av.top 1743                     + c_none)
1744             return
1745
1746         if inuse_bit_at_offset(nextchunk, chunksize(nextchunk)):
1747             print(c_none + " [*] prev_inuse bit set on chunk after nextchunk")
1748         else:
1749             print(c_error + " [_] ERROR: PREV_INUSE bit of chunk after", end=‘ ‘)
1750             print("nextchunk (0x%x) is not set" % 1751                     (nextchunk.address + chunksize(nextchunk)) + c_none)
1752             return
1753
1754         print(c_header + "\np (0x%x) will be written to fwd->bk (0x%x)" 1755                 % (p.address, fwd+0xC) + c_none)
1756
1757     def fast_bin_method(self, p):
1758         p = malloc_chunk(addr=p, inuse=True, read_data=False)
1759
1760         print(c_none + "Checking chunk p")
1761         print(c_none + " [*] p = " + c_value + "0x%x" % p.address + c_none)
1762
1763         if p.address < gdb.parse_and_eval("(unsigned int)%d" % -chunksize(p)):
1764             print(" [*] size does not wrap")
1765         else:
1766             print(c_error + " [_] ERROR: p > -size" + c_none)
1767             return
1768
1769         if chunksize(p) >= MINSIZE:
1770             print(" [*] size is >= minimum chunk size")
1771         else:
1772             print(c_error + " [_] ERROR: chunksize(p) < MINSIZE" + c_none)
1773             return
1774
1775         if chunksize(p) < get_max_fast():
1776             print(" [*] size is in fastbin range")
1777         else:
1778             print(c_error + " [_] ERROR: size is not in fastbin range" + c_none)
1779             return
1780
1781         if chunk_non_main_arena(p):
1782             print(" [*] non_main_arena flag is set")
1783         else:
1784             print(c_error + " [_] ERROR: p‘s non_main_arena flag is NOT set")
1785             return
1786
1787         if prev_inuse(p):
1788             print(" [*] prev_inuse bit is set")
1789         else:
1790             print(c_error + " [_] ERROR: PREV_INUSE bit is not set, this will", end=‘ ‘)
1791             print("trigger backward consolidation" + c_none)
1792
1793         print(c_none + "\nChecking struct heap_info")
1794         print(c_none + " [*] struct heap_info = " 1795                 + c_value + "0x%x" % heap_for_ptr(p.address))
1796
1797         inferior = get_inferior()
1798         if inferior == -1:
1799             return None
1800
1801         try:
1802             mem = inferior.read_memory(heap_for_ptr(p.address), SIZE_SZ)
1803             if SIZE_SZ == 4:
1804                 ar_ptr = struct.unpack("<I", mem)[0]
1805             elif SIZE_SZ == 8:
1806                 ar_ptr = struct.unpack("<Q", mem)[0]
1807         except RuntimeError:
1808             print(c_error + " [_] ERROR: Invalid heap_info address 0x%x" 1809                     % heap_for_ptr(p.address) + c_none)
1810             return
1811
1812         print(c_none + " [*] ar_ptr = " + c_value + "0x%x" % ar_ptr)
1813         print(c_none + "\nChecking struct malloc_state")
1814
1815         #test malloc_state address
1816         try:
1817             mutex = inferior.read_memory(ar_ptr, SIZE_SZ)
1818         except RuntimeError:
1819             print(c_error + " [_] ERROR: Invalid malloc_state address 0x%x" % 1820                     ar_ptr + c_none)
1821             return
1822
1823         av = malloc_state(ar_ptr)
1824
1825         if av.mutex == 0:
1826             print(c_none + " [*] av->mutex is zero")
1827         else:
1828             print(c_error + " [_] ERROR: av->mutex is not zero" + c_none)
1829             return
1830
1831         print(c_none + " [*] av->system_mem is 0x%x" % av.system_mem)
1832
1833         print(c_none + "\nChecking following chunk")
1834         nextchunk = chunk_at_offset(p, chunksize(p))
1835         print(" [*] nextchunk = " + c_value + "0x%x" % nextchunk.address)
1836
1837         if nextchunk.size > 2*SIZE_SZ:
1838             print(c_none + " [*] nextchunk size is > 2*SIZE_SZ")
1839         else:
1840             print(c_error + " [_] ERROR: nextchunk size is <= 2*SIZE_SZ" +c_none)
1841             return
1842
1843         if chunksize(nextchunk) < av.system_mem:
1844             print(c_none + " [*] nextchunk size is < av->system_mem")
1845         else:
1846             print(c_error + " [_] ERROR: nextchunk size (0x%x) is >= " % 1847                     chunksize(nextchunk), end=‘ ‘)
1848             print("av->system_mem (0x%x)" % (av.system_mem) + c_none)
1849             return
1850
1851         fb = ar_ptr + (2*SIZE_SZ) + (fastbin_index(p.size)*SIZE_SZ)
1852         print(c_header + "\np (0x%x) will be written to fb (0x%x)" 1853                 % (p.address, fb) + c_none)
1854
1855
1856 ################################################################################
1857 # INITIALIZE CUSTOM GDB CODE
1858 ################################################################################
1859 heap()
1860 print_malloc_stats()
1861 print_bin_layout()
1862 check_house_of_mind()
1863 gdb.pretty_printers.append(pretty_print_heap_lookup)

时间: 2024-10-30 16:16:01

Kali下使用libheap的相关文章

Kali下的内网劫持(四)

在前面我都演示的是在Kali下用命令行的形式将在目标主机上操作的用户的信息捕获的过程,那么接下来我将演示在Kali中用图形界面的ettercap对目标主机的用户进行会话劫持: 首先启动图形界面的ettercap: 接下来将嗅探方式修改为同意嗅探,且嗅探网卡为eth0: 接下来进行在同一局域网内的主机扫描: 可以看出扫描出的主机还不少: 添加目标主机: 添加路由: 接着进行ARP毒化: 开始嗅探之后选择连接的主机: 在目标主机上访问并登录某一页面: 那么在劫持断可以看到访问的网站以及登录的用户名和

Kali下进行局域网断网攻击

今天我就来演示一下在kali下的局域网断网攻击,即ARP地址欺骗,下图所要用到的arp地址欺骗状态图: 则: 第一步:假设主机A访问某网站,那么要告知某网站我的IP和MAC地址,但这是以广播的方式告知的: 第二步,由于是广播方式告知,猥琐的B主机也知道了A的IP和Mac地址,于是猥琐的B主机把自己伪装成某网站,给A发送回复,A误以为B就是某网站,因此更新了自己本机的ARP缓存: 第三步,两者建立连接,A不断将自己的请求发给B,可怜的某网站被挂在一遍了.如果B又把自己伪装成主机A,从而转发A的请求

Kali下安装Java环境

<-----教你在Kali下安装Java环境-----> 1. 下载1.8u121的JAVA JDK 下载地址:http://java.sun.com/javase/downloads/index.jsp 2. 解压缩文件并移动至/opt tar -xzvf jdk-8u91-linux-x64.tar.gz mv jdk1.8.0_91 /opt cd /opt/jdk1.8.0_91 3. 设置环境变量 执行 gedit ~/.bashrc , 并添加下列内容 # install JAVA

Kali下安装中文输入法

1.打开终端: 2.使用vim或者gedit打开 /etc/apt 目录下的sources.list vim /etc/apt/sources.list 或者 gedit /etc/apt/sources.list 3.添加如下一些镜像源(速度会快点而已) deb http://http.kali.org/kali kali main non-free contrib deb-src http://http.kali.org/kali kali main non-free contrib deb

Kali下安装Nessus

Nessus是一款商业的漏洞扫描工具,当然它也提供用于个人使用的免费版,但是对其中一些功能进行了限制. 打开地址:http://www.tenable.com/products/nessus/nessus-plugins/obtain-an-activation-code 希望这个地址在你看到时还没有失效,这个地址显示了Nessus各版本的下载地址,如下图: 在图中的右侧显示的就是免费的Nessus Home,可以看到价格的位置显示的是Free.点击下面的Register Now按钮进行简单的注

kali 下安装 vmtools

网上的教程都是默认路径下的,kali是定制版本的,路径不同,所以首先要找到media下安装包的路径,然后进入该路下,将安装包复制到想要的路径下,并解压缩到想要的路径下,剩下的就跟网上的差不多了,即找到安装路径,运行安装程序. 现在有个问题是header -------------------------------问题已解决:直接在安装时 加一个参数 -d 这样不用自己再选择参数,一路自动默认,ok. 参考文章 http://www.360doc.com/content/14/1006/10/6

kali 下程序卸载方法

kali中主要为2种卸载方法: 1.apt 2.dpkg 使用apt的方式有: apt-get remove [package] apt-get remove --purge # ------(package 删除包,包括删除配置文件等) apt-get autoremove --purge # ----(package 删除包及其依赖的软件包+配置文件等 使用dpkg dpkg -r     #移除一个已安装的包. dpkg -P    #完全清除一个已安装的包.和 remove 不同的是,r

kali下添加PATH环境变量

添加PATH环境变量,第1种方法: [[email protected]_web_s1 ~]# export PATH=/usr/local/webserver/mysql/bin:$PATH 再次查看: [[email protected]_web_s1 ~]# echo $PATH         /usr/local/webserver/mysql/bin:/usr/local/webserver/mysql/bin/:/usr/kerberos/sbin:/usr/kerberos/bi

ZendStudio在kali下无法启动

错误如下 # # A fatal error has been detected by the Java Runtime Environment: # #  SIGSEGV (0xb) at pc=0x00007f861417273f, pid=31502, tid=140214257428224 # # JRE version: 6.0_31-b31 # Java VM: OpenJDK 64-Bit Server VM (23.25-b01 mixed mode linux-amd64 co