chall.exe is a 3,072 byte PE32 that barely does anything on its own. It allocates RWX memory, copies 674 bytes into it and calls the result.
That little blob is the actual challenge. It starts in x86, escapes into x86-64 through Heaven’s Gate, decrypts the next x86 stage and switches back. Then it does it again.
i spent much less time on the crypto than on making sure i had Binary Ninja in the right architecture. The same bytes look valid in both modes. Wrong mode, plausible assembly, complete bullshit.
This was also my first time using Binary Ninja Cloud. i honestly expected a restricted demo. It handled the challenge just fine.
The interesting part is not that AI can run security tools. Everyone can ask an agent to run nmap, nuclei, sqlmap, or whatever the tool of the week is. That is not the hard part. That is just a faster command line with more confidence than it deserves.
The actual trick is building a system where the agents are not trusted blindly.
The core pattern is:
1
separate personas + validation gates + feedback loops = consistently better outcomes
That is what the talk is really about.
Security is just the domain where i currently have the loudest proof.
What i built
The current setup is a validation-first vulnerability research platform.
At the center is one canonical backend: state, orchestration, findings, submissions, operator UI. Around that sits a distributed execution layer with pwn hosts, a shared bounty-cli, and a growing pile of specialized agents and skills.
The rough shape:
central server as source of truth
Go backend and persistent state
NixOS flakes for reproducible infra
bounty-cli on worker hosts
4 pwn hosts for distributed execution
56 specialized agents
200+ reusable skills
platform ingestion across HackerOne, Bugcrowd, YesWeHack, Intigriti, HackenProof, Immunefi, Apple Security, and Google VRP
The agents are not “one hacker bot.”
They have roles.
Recon agents do recon. Exploit agents attempt bounded exploit paths. Verification agents independently check findings. Chaining agents try to turn validated low-severity artifacts into higher-value outcomes. Feedback updates the prompts, profiles, routing rules, and future runs.
That separation matters.
If one model does discovery, exploitation, verification, report writing, and final confidence scoring in one long session, you’re not building an automation platform. You’re building a hallucination amplifier.
The results
The ranking followed real findings, not vibes.
Public and semi-public outcomes include:
Keycloak CVE-2026-1190
ClickHouse RBAC bypass work that landed as a critical fix
3x Amazon VDP subdomain takeovers
OANDA VDP subdomain takeover
Opera SIP / VoIP infrastructure takeover
Ruby on Rails valid finding
The Opera one is a good example of why this kind of automation works.
The rig flagged dangling SRV records:
1 2
_sip._tcp.opera.com. 86400 IN SRV 0 0 5060 e1.viju.vc. _sips._tcp.opera.com. 86400 IN SRV 0 0 5061 e1.viju.vc.
e1.viju.vc pointed to a domain that no longer existed. Any RFC 3263 compliant SIP client resolving Opera’s SIP records would end up talking to whoever controlled that domain.
The automation found the edge case.
I registered the domain manually, pointed it at my infrastructure, confirmed the takeover, and reported it through Bugcrowd.
That distinction is important: machines detect, humans approve irreversible steps.
I do not want an AI agent registering random domains, touching third-party infrastructure, or deciding on its own when something is safe to prove. That is exactly the kind of cowboy bullshit that gets people into trouble.
Why MCP got dropped
The first version had more MCP in it.
MCP is great for prototyping. It is convenient, structured, and makes tool access easy.
But for this workload, the token math gets ugly fast.
Full tool schemas get shoved through the model again and again. Tool count grows, context overhead grows. Five tool calls can become five inference loops. At campaign scale, that is just burning money for the privilege of doing IPC through a language model.
So i moved the execution path to a shared Go CLI.
The model reasons. The CLI executes locally. Skills are injected only when needed. Results go back to the server.
Same coverage. Much less token waste.
In practice, this was the difference between a cool prototype and something i can actually run all day.
The Claude Code part
Since this is a Claude Code meetup, i am also talking about how the platform itself was built.
The short version:
Claude Code was useful because i constrained it.
Not because i typed:
1 2
Build me a billion dollar business. Make no mistakes!
or the security version:
1 2
Find me a $100k bug bounty! No false positives!
That is not how any of this works.
The build process followed the same loop as the runtime system:
one feature per session
define the validation gate before implementation
implement the smallest useful slice
run checks
fix until green
only then move to the next layer
CLAUDE.md and memory carry the persistent project context. The prompt carries the task. The tests carry the definition of done.
This is the part most people skip.
They treat every AI session like the model should magically understand their architecture, their history, their taste, their production constraints, and the weird thing they decided three months ago at 2am.
It doesn’t.
Every session is a new hire.
An extremely fast, A-grade new hire with every tool installed, but still a new hire. If you don’t onboard it properly, it will produce generic code that technically works and architecturally sucks.
The portable pattern
The point of the talk is not “go build a bug bounty robot.”
The point is that the same loop works outside security.
For example, upgrading GitLab on Kubernetes is the same pattern.
You don’t prompt:
1
Upgrade GitLab and don't break production.
You prompt in phases.
Explore read-only. Take backups. Research the version path. Do not skip required intermediary versions. Upgrade one hop. Validate the services. Only proceed when the previous hop is healthy. Feed failures back into the next attempt.
That is how you get from GitLab v15 to v18 without turning your Kubernetes cluster into modern art.
The actual takeaway
Do not start with one giant prompt.
Start with a loop.
Split the work into phases. Give each phase a role. Define what artifact comes out of it. Validate that artifact before anything else consumes it. Chain only validated outputs. Feed failures back into the next run.
That is the boring engineering part.
Which is why it works.
I got to #2 on the German HackerOne VDP leaderboard not because i found a magic prompt, but because i built a system that rejects garbage before it reaches me.
VDPs still don’t pay. I said that before and it’s still true. But they build reputation, they open private doors, and they are a good proving ground because the surfaces are less farmed than paid BBPs.
If you want this kind of validation-first automation pointed at your own infrastructure before someone else points something dumber and more hostile at it, get in touch.
I don’t think people really understand what losing each of you did to me.
With every one of you that died, something in me got worse. Something got darker. My humor turned another notch blacker, more bitter, more sinister. Not because I wanted it to. It just happened. Loss after loss after loss, and now I can feel it in the way I think, the way I talk, the way I look at life.
It’s been close to five months since Fussel left this realm. It is getting easier. Slowly. Very slowly. But I still miss your touch every single day. Every night. Every time I make coffee. Every time I leave my office. Every time I walk out of that room and there is no you waiting there, no little moment, no little routine, no little piece of comfort.
Right now the joy of leaving my home office feels close to the minimum possible. That house, this whole daily routine, all of it feels emptier without you. And I don’t mean in some dramatic way. I mean in the real way. In the everyday way. In the way I wake up already knowing you’re not there. In the weight on my chest when I try to fall asleep. In the kind of silence that does not feel peaceful, only wrong.
Two new rescues have joined the household. One of them even looks a bit like Fussel, though I did not pick them for that reason. They deserve love, and they get it. But life has not become better by any measure or means. If anything, it has just become sadder without you. They do not fill that void. They cannot. That place is yours.
I even have pictures of all of you rotating on my Apple Watch. It hurts to see your faces every day. Maybe that’s why I only wear it on my two workout days each week now. Because every glance at my wrist is a reminder of all of you, and of the fact that none of you are here anymore.
What hurts even more is that your faces are slowly fading from my memory. I wish that was not true. I want to be better than that. I want to remember every detail forever. But I ain’t. And that pain sits deep, because it feels like losing small pieces of you all over again.
People say time helps. Maybe it does. A little. Enough to keep moving, maybe. But it does not bring any of you back. It does not make the house feel alive again. It does not make me whole again.
I wish to rejoin all of you one day. And these days, with how miserable I feel, I can’t even honestly say that thought scares me the way it should.
I miss all of you. More than I can explain. And parts of me went with you.
my agents found a vulnerability in KeyCloak. not a duplicate this time—a valid CVE assigned. the discovery was fully automated; the agents identified the weak point and i verified the exploit path. if you’re running KeyCloak, patch it.
ClickHouse - Critical Bug Fix
i found a permission bypass in ClickHouse’s BACKUP/RESTORE operations that allowed:
RESTORE execution in readonly mode (it modifies data—this should never have been possible)
The internal setting being exploited in initial queries (meant only for ON CLUSTER secondary queries)
Bypassing BACKUP permission checks by establishing S3/remote connections before access verification
the fix (PR #94617) was merged as a critical bug fix impacting RBAC. my report closed clickhouse-private#45780. this is what happens when you point AI agents at database source code—they find logic errors humans miss during code review.
Opera.com SRV Record Takeover
my rig identified dangling SRV records pointing to e1.viju.vc. two records:
1 2
_sip._tcp.opera.com. 86400 IN SRV 0 0 5060 e1.viju.vc. _sips._tcp.opera.com. 86400 IN SRV 0 0 5061 e1.viju.vc.
RFC 3263 compliant SIP clients connecting to opera.com would resolve to attacker-controlled infrastructure. the agents detected it; i registered the domain manually (for obvious reasons) and reported it. this is the kind of legacy infrastructure vulnerability that automated recon excels at finding.
The Rankings
i’m now #8 in Germany on HackerOne (VDP + BBP combined) and #2 for VDP alone(leaderboard). the path to #1? two of my 3 subdomain takeovers currently in triage—one of which is the 400+ domain campaign. that one is already completed, but triage on that scale takes time.
Financial Reality Check
the rig is not profitable yet.
i’ve spent more than i’ve earned. why? strategy. i’ve focused heavily on VDP programs—no payouts, but easier attack surfaces for building reputation and getting those crucial private program invites. the leaderboard position (#2 VDP in Germany) is just a nice side effect. subdomain takeovers also have real costs (domain registrations, infrastructure), and i spent the first two weeks of january perfecting the automation.
this is a reputation-first, profit-later play. private programs and Bug Bounty programs pay. VDPs don’t. but VDPs aren’t farmed as heavily as BBPs since there’s no money in it, making them easier surfaces to find bugs on. you need the reputation to get the invites—and it’s working: i’ve received 30+ private invites across HackerOne, Bugcrowd, YesWeHack, and HackenProof. smart contracts? i’m already tackling them—but it’s really fucking hard.
What’s Changed in the Rig
the multi-stage, phase-based workflow (Recon → Exploit → Verify) is now locked in. the early “invalid” reports—the AI hallucinations—are gone. current workflow:
agents recon and identify targets
specialized exploit agents probe for specific vulnerability classes
verification agents independently confirm findings before i see them
this reduces false positives to near zero. when a report hits my queue, it’s already been validated by a second AI agent.
The Claude Divorce
i completely ditched Claude Code (and my $200/month Max subscription). why? Anthropic banned me for using OpenCode. i’m not even appealing it—they’ve been nerfing their models too hard over the past 6 months anyway. it’s a constant up and down of model quality that i don’t want to partake in anymore.
my new stack:
OpenAI Max subscription for the heavy lifting
Chinese models via OpenRouter using the only parameter to whitelist US providers:
Kimi K2.5
DeepSeek V3.2
MiniMax 2.1
quality-wise? roughly between Sonnet 4.5 and Opus 4.5 depending on the task and model. and the pricing? about 1/100 of Anthropic costs. for $200, i get heavily subsidized access. even the US providers on OpenRouter somehow match those chinese prices.
The Bottom Line
findings driving these rankings are AI-generated. i’m not manually running sqlmap or crawling JavaScript. i steer. i decide which targets to prioritize. i handle the manual steps that require human judgment (like domain registration for takeovers). but the discovery? that’s the machines.
the pivot is working. the rig is producing. and we’re just getting started.
I am currently open for contractual engagements.
if you want me to point this system at your infrastructure before someone else does, get in touch.
Let’s be real for a second. The project market for freelance developers in Germany right now? It’s basically dead. The economy is weird, budgets are frozen, and everyone is sitting on their hands.
But i’m not the type to sit around.
For those who don’t know my history, i was deep in the blackhat community back in the early 2000s (until about 2005). I’m not talking about running scripts i found on a forum; i’m talking about deep research. My most notable pwns from that era have never been discovered to this day, and i intend to keep it that way.
Fast forward to 2025. I’ve spent the last few years building high-end AI products and consulting. I realized i had two things: a deep understanding of offensive security from my youth, and a mastery of the modern AI stack.
So, i pivoted. I built a war machine.
Meet the Rig
I didn’t just write a python script that wraps Nmap. I built a fully distributed, AI-orchestrated bug bounty automation platform running on NixOS.
It’s a beast that runs while i sleep.
The Architecture
At its core, it is a distributed system managed by a central orchestrator (kistel) and a fleet of execution nodes (pwn1 through pwn4).
Infrastructure: Everything is defined in NixOS flakes and deployed via deploy-rs. If a node gets tainted or i need more compute, i just spin it up, and the state configuration handles the rest.
The Brain: A custom Go 1.25 backend backed by PostgreSQL 17 (sharding across 32 distinct table structures).
The Muscle: A fleet of VMs loaded with 40+ standard security tools (Nuclei, Ffuf, SQLMap, etc.), but—and this is the key—driven by AI agents.
The AI Advantage: Multi-Model Orchestration
Most people trying to use AI for hacking just paste code into ChatGPT and ask “is this vulnerable?”. That’s amateur hour.
My system uses a Multi-LLM Orchestration layer. I use CLIProxyAPI to bundle all my various subscriptions behind a single Claude Code compatible API. This allows the orchestrator to dynamically route tasks to the model best suited for the job:
Claude (Opus/Sonnet 4.5): Handles the high-level logic, exploit chaining, and “creative” thinking.
MiniMax M2 & Kimi K2: My daily workhorses for context-heavy tasks (like dumping entire repo structures or massive JS files).
GPT-5.2 Codex: Used strictly for generating exploit payloads and proof-of-concept scripts.
It’s Not a Script, It’s an Organization
I designed the system to function like a cyber-crime syndicate, but automated.
1. The Agent System (42+ Agents) I have specialized agents for different domains. I don’t just have a “hacker bot.” I have:
Recon Agents: Web discovery, deep GitHub dorking, subdomain enumeration.
Exploit Agents: Specialized in XSS, SSRF, SQLi, GraphQL, and even CI/CD supply chain attacks.
Blockchain Agents: Deep analysis of Move language contracts (Sui/Aptos), detecting specific vulnerabilities like Hot Potato pattern violations, Shared Object DoS, Flash Loan logic errors, and simulating MEV sandwich attacks.
Apple Silicon Agents: Specialized in XNU kernel exploitation, PAC/Canary intersection analysis, and BlastDoor sandbox escapes.
2. The Skills System (100+ Skills) The agents are equipped with “skills”—modular capabilities that they can activate on demand. Need to bypass a specific JWT implementation? There is a skill for that. Need to race a database transaction? The agent activates the RaceCondition skill and executes.
3. Automated Workflow The system automatically syncs programs from HackerOne, Bugcrowd, Intigriti, YesWeHack, and Hackenproof. I’ve also manually imported targets from Google VRP and Apple Security Bounty, since they don’t operate as traditional bounty platforms.
Ingest: It pulls the scope.
Plan: LLMs analyze the scope and group targets based on technology stacks.
Execute:bounty-cli triggers the campaign.
Chain: If an agent finds a low-severity bug, it pings the Orchestrator, which might spin up a different agent to try and chain it into a critical.
Submit: The system auto-formats the report, writes the reproduction steps, and even handles the initial triage Q&A via an auto-answer service.
Successes (and Failures) so far
During the first week of operating the v1 prototype of this rig, i managed to report valid duplicates. While “duplicate” might sound bad to some, to me, it was pure gold. It validated my entire idea. It proved that my AI agents were finding the same bugs as human hunters, just faster and while i was asleep.
Currently, 2 of my issues are in active triage and looking good.
Of course, it wasn’t all smooth sailing. Early on, i had a couple of “Invalid” reports—classic AI hallucinations where the model thought it saw a vulnerability that wasn’t there. That failure was actually the catalyst for refining my approach into the multi-stage, phase-based workflow (Recon -> Exploit -> Verify) i use now.
I also still have a bunch of reports on HackerOne that are sitting in “Unread” or “No-Reply” limbo. In two specific cases, the triager promised to reopen the ticket if i proved X. I proved X in both cases. I haven’t heard back yet.
But honestly? Coming from doing blackhat hacking 20-odd years ago, to playing CTFs for fun, and now transitioning to legitimate Bug Bounties is quite the journey. Even if it hasn’t yielded massive financial success yet, the validation is there. The machine works.
I am currently open for contractual engagements.
If you want this rig pointed at your infrastructure to find the holes before a state actor or a ransomware gang does, contact me. You can hire a consultancy that throws a junior pentester at your API for a week, or you can hire me and my army of 42+ AI agents.
Over the last few years, i’ve immersed myself completely in the AI landscape. I’m not just talking about playing with ChatGPT for fun; i’m talking about high-level consulting, training and running my own models in my own racks here in Nuremberg, Germany, and building scalable services on top of this emerging tech.
Through all of this, if there is one lesson i’ve learned that i need to hammer home, it’s this: it’s by far not all great, but we are also far from the “doom and gloom” scenario that a lot of conservative IT guys make it seem.
The “All-Knowing Oracle” Fallacy
The single biggest issue i see in the industry right now is professionals treating AI as an all-knowing oracle. It is not. It is a probabilistic engine with a hard training cutoff.
If you are asking it for recent frameworks, zero-day exploits, or bleeding-edge library changes without deep research or web search capability enabled, you will get old or wrong information. That is not the AI being “stupid” or “useless”—that is you using the tool incorrectly.
You wouldn’t use a hammer to drive in a screw and then complain that the hammer is broken.
It’s a Tool, Not a Replacement
This technology is nothing more than a new, incredibly powerful tool in your tool belt. It is not a god-tool that solves architecture problems by magic. But, if you take the time to actually master the AI CLI tools, you can command them to control your system with ease or develop boilerplate and logic faster than you can physically type.
The barrier to entry here is the willingness to learn. Learn the specific quirks of the models, learn how to prompt correctly, and mastery will follow.
The Cost of Mastery (and how to mitigate it)
I hear the complaints constantly: “I’m not paying $20 for ChatGPT” or “$200 for the good Claude plan is too much.”
Look, if you want professional results, you need professional tools. However, i know the subscriptions add up, especially when you need access to the absolute top-tier context windows.
Here is a hot tip for the budget-conscious:
You can grab legitimate accounts on marketplaces like G2A for a fraction of the enterprise price.
We are talking about a $200 subscription tier for roughly ~$20. Disclaimer: You are buying a pre-provisioned account, not upgrading your personal one. Just make sure you understand the trade-offs. No account sharing, but it’s a new login every month.
My Current “Daily Driver” Loadout
The landscape changes weekly, but as of late 2025, this is what i am actually running in production:
1. Context Heavy Lifting: MiniMax Plus/Max ($20/$50). This has been my daily workhorse for anything requiring massive context. When you need to dump an entire repository into the prompt to refactor a legacy module, this is currently the king.
2. Integration & Logic: Google Gemini CLI & Gemini 3 Pro. These past couple of days, this has been a standout performer. It handles system integration and logical reasoning surprisingly well, often beating out the others on complex instruction following.
3. The “Classic” Options: I still maintain subscriptions for Claude Code and OpenAI Codex, but it feels like they are constantly playing games with their user base. They release a ground-breaking model, get everyone hooked, and then silently nerf it to save on backend compute costs once scaling becomes an issue.
I find myself constantly toggling between max subscriptions for both. It’s an endless cycle of GPT 5, 5.1, 5.2, followed by Claude retorting with Sonnet 4.5, Opus 4.5, and Haiku 4.5. The quality fluctuates wildly, so you need to be agile and willing to switch providers.
(Side note: It is genuinely sad that Deepseek and Kimi don’t offer a dedicated code subscription yet. I’d jump on that in a heartbeat.)
A Real World Case Study: The GitLab Upgrade
To prove this isn’t just theoretical, here is a recent win. I successfully used Claude Code to upgrade a self-hosted GitLab instance from v15 to v17.
If you’ve ever managed GitLab, you know the upgrade paths are treacherous. This instance was running on Kubernetes, adding a massive layer of complexity. We even hit a snag where the PostgreSQL version requirements changed mid-stream; i was running an old v13 instance from a time when pg_upgrade automation wasn’t standard yet (though it is now), and it handled that transition flawlessly too.
It took about a day. I didn’t just tell the AI “upgrade this”—that would be suicide. I commanded it to perform backups. I had it verify migration paths. I had it check for deprecations. The AI was the hands, but i was the supervisor.
The result? Zero data loss. Full upgrade completed in about 24 hours. A human team debugging the Helm charts, migration failures, and PostgreSQL schema changes would have likely taken three times as long.
The Golden Rule: Context and Verification
Here is the trick that makes this viable in production: always prompt the AI to verify what it just did after every command.
Do not just “rawdog” a sequence of 20 commands blindly and then discover “whoopsie, i deleted your prod db.” You need to be explicit. Tell it: “This IS the production deployment. Be careful.”
It can be a tremendously effective engineer and problem solver, but only if you let it in on the details.
If you assume it should know that prd5.xyz.gcp... is your production environment, ask yourself: would a trainee or a fresh new hire understand that context immediately? Probably not.
So treat the AI like that new hire. Give it the full context. Tell it the stakes. And force it to verify its own work step-by-step.
The Plumber Analogy
This brings me to the most critical point: Do not use AI for tasks where you cannot judge the output.
It is basically a super-fast typewriter for your ideas. Use it to accelerate your workflow.
However, if you veer off into territory you don’t understand—if you ask it to write kernel modules when you don’t know C, or manage a Kubernetes cluster when you don’t understand pods—you will end up with a destroyed home directory or a compromised production database.
If used correctly, it is a humongous multiplier for any IT professional. If used incorrectly, it is a liability.
Think of it like a plumber. If a plumber doesn’t know their tools and floods a client’s bathroom, it isn’t the wrench’s fault. It’s the plumber’s fault.
It’s your fault.
If you’re in IT (otherwise you probably would not be reading this), your sole job is to constantly learn new tools and emerging things. If you’re not doing that, then maybe IT isn’t for you?
In any case: this is a new tool and most of us should at least learn how to use it. It will make a massive impact on how much time you actually spend solving problems versus solving the “problems around your actual problems.” We all know the drill: you just wanted to add a user, but some certificate expired, then some policy needed updating from the last version, and suddenly it’s 3 hours later.
Why not just have the AI do that in the background? Send it off, fetch yourself a coffee, call someone, or clear a few 5-minute tasks from your list. The amount of times per day where i can knock out small tasks because the big stuff—the stuff that usually requires huge amounts of focus—now only requires me to review, steer, and manage, is life-changing.
I’ve basically become a manager and reviewer of 10 virtual me’s. By now, i’ve got them almost behaving like me and doing things exactly like i’d do them. Make use of this. Use it to free up your day for other things like playing video games, going outside, or spending time with your pets—or go full 100x engineer and be your own company of 30 (10 virtual employees working round the clock is basically 30 FTEs).
Stop whining, pay the few bucks, and actually learn to use the tools of your trade.
You’ve probably heard about the new Generative Fill feature in the upcoming Photoshop version. Well i’ve come bearing good news, it’s public, available for everyone with an Adobe Creative Cloud Subscription, and it’s called Adobe Photoshop 2024.
Now i’ve been using the AI features in Photoshop Beta since it came out a couple of months ago, and i must say that i’m very happy about what Adobe has put together.
These AI features almost creep into every other thing Adobe Photoshop does.
Object Select
Now with AI power, it’s even easier to select objects inside your images, no need to use a Lasso for drawing odd shapes anymore.
Editing layers
Having a layer and just editing it’s prompt to get new variations might be the most mind blowing feature of them all.
Editing the Sky
Go to the select menu and pick Sky, now you can use generative fill to make a whole new sky.
so much more
Over time, i think we will find more and more of these helper features that make using Adobe Photoshop really something new.
Yeah i lied, it’s actually 6 things you’re doing wrong.. My bad.
Since y’all probably have used Midjourney V5 in the past 6 months or so, i wanted to share a couple of tips and tricks to improve your Prompts. This works for most AI image generators such als Dall-E, Midjourney, Gencraft, etc.
What are prompts?
I’m pretty certain that 80% of the english speaking IT folks know this, but i’ll do it for the 80% of german IT engineers who have no fucking clue.
Prompts are the thing you tell the AI to do. You prompt it to draw an image of “gay pirate wearing a nazi pyjama”, and it will do so. The prompt is your Input for most of the current Transformer based models.
Tip 1 - make your prompts shorter
Having ver long prompts doesn’t help. It’s not like horsepower where more is better, it’s about being precise and concise. Almost like talking to your girlfriend. The more you talk, the deeper the trouble gets. Just stay on point.
Tip 2 - not providing enough constraints
Same thing, if you don’t give your girlfriend any constraints, then god knows, she’ll start buying import beer or Rosé. Same goes for AI image generators. Open ended prompts without guidance will produce random results, nothing you can repeat or use. For example “Spaceship” or “Airplane” might be too general, try something like “an American Airlines Airplane” or “a futuristic spaceship, star trek style, entering a wormhole”.
Tip 3 - ambiguous language
You need to be very clear, or your Girlfriend^WAI will have issues. Avoid pronouns and implied subjects that can confuse the Girlfriend^WAI.
Tip 4 - abstract concepts
Just like your girlfriend, abstract concepts make the AI’s head hurt. It has no idea about emotions, so instead of having your a AI prompt be like “Painting of a happy female” be “Painting of a smiling female”. AI will the know what smiling is, but what emotion/abstract concept lies behind “happy” might be going too far.
Tip 5 - being impatient
So the first result that Dall-E or Midjourney yielded isn’t perfect. You’re giving up of course… But nobody told you that it can take several attempts, and especially learning, for how to craft your prompts correctly.
Depending on the model your AI has been trained on, you will need to play around to become proficient. Have you ever heard of the 8 year old car mechanic? Exactly.
Tip 6 - use ChatGPT to create your ideal prompts
Now here comes the kicker. Instead of retraining your brain to write these stupid prompts, you could also just ask ChatGPT (gpt-4) to write them for you.
Priming ChatGPT
1
You are an AI model developed by OpenAI, and I’m introducing you to Midjourney, an AI tool that generates images based on text prompts. Your task is to assist me in creating these prompts. Are you ready?
Examples
You should pass ChatGPT some examples of good prompts, for it to know what you’re looking for.
1 2 3 4
Some examples of really good prompts are: - “A serene mountain landscape covered in a blanket of snow, rendered in a minimalist style, capturing the subtle shades of white and blue under the soft morning light.” - “A futuristic cityscape at night, illuminated by neon lights and towering skyscrapers, depicted in a cyberpunk art style with a strong emphasis on the contrast between the dark shadows and vibrant glow.” - “A bustling market scene in a bustling Asian city, portrayed with a lively and vibrant palette, highlighting the intricate patterns of textiles and the busy atmosphere with dynamic brushstrokes.”
For instance, you can ask:
1
Can you generate a prompt for an image of a beach under a starry night sky?
Or you can phrase your query like this:
1
Title: “A beach under a starry night sky.”
ChatGPT will then create a prompt based on the provided concept:
1
Prompt: “A tranquil beach scene beneath a studded night sky, rendered in an impressionistic style. The sands are soft and glistening, reflecting the brilliant stars above. The gentle waves ebb and flow with a mesmerizing rhythm, the whitecaps gleaming under the stellar glow. The calm serenity of the ocean and the enigmatic vastness of the starry night sky paint a breathtaking tableau.”
I finally got around to setting up a new mailserver and i decided to give OpenSMTPD a try. It wasn’t a natural birth, i can tell you that. The switching of the configuration syntax makes for a lot of outdated Google Search results.
So what are we going to setup. Well the title gave it away i guess, so for the slow ones amongst you: we are building a Mailserver with OpenSMTPD, Dovecot, RSpamd and Sieve. The OpenSMTPD and the Dovecot will both be using the same authentication table and hashing scheme, making this a nifty solution.
psql -Upostgres <<EOF CREATE USER mail WITH ENCRYPTED PASSWORD 'your.mail.password'; CREATE DATABASE mail OWNER mail; EOF
psql -Umail mail <<EOF
-- this is the table for the users accounts CREATE TABLE public.accounts ( id serial, email character varying(255) DEFAULT ''::character varying NOT NULL, password character varying(255) DEFAULT ''::character varying NOT NULL, active boolean DEFAULT true NOT NULL );
-- this is the table for the virtual mappings for email -> email CREATE TABLE public.virtuals ( id serial, email character varying(255) DEFAULT ''::character varying NOT NULL, destination character varying(255) DEFAULT ''::character varying NOT NULL );
-- this view is used to determine where to deliver things CREATE VIEW public.delivery AS SELECT virtuals.email, virtuals.destination FROM public.virtuals WHERE (length((virtuals.email)::text) > 0) UNION SELECT accounts.email, 'vmail'::character varying AS destination FROM public.accounts WHERE (length((accounts.email)::text) > 0);
-- this view is used to determine which domains this server is serving CREATE VIEW public.domains AS SELECT split_part((virtuals.email)::text, '@'::text, 2) AS domain FROM public.virtuals WHERE (length((virtuals.email)::text) > 0) GROUP BY (split_part((virtuals.email)::text, '@'::text, 2)) UNION SELECT split_part((accounts.email)::text, '@'::text, 2) AS domain FROM public.accounts WHERE (length((accounts.email)::text) > 0) GROUP BY (split_part((accounts.email)::text, '@'::text, 2));
-- this view should control the email addresses users can send with CREATE VIEW public.sending AS SELECT virtuals.email, virtuals.destination AS login FROM public.virtuals WHERE (length((virtuals.email)::text) > 0) UNION SELECT accounts.email, accounts.email AS login FROM public.accounts WHERE (length((accounts.email)::text) > 0); EOF
/etc/mail/postgres.conf
Next we configure the PostgreSQL lookups for smtpd:
1 2 3 4 5
conninfo host='localhost' user='mail' password='your.mail.password' dbname='mail' query_alias SELECT "destination" FROM delivery WHERE "email"=$1; query_credentials SELECT "email", "password" FROM accounts WHERE "email"=$1; query_domain SELECT "domain" FROM domains WHERE "domain"=$1; query_mailaddrmap SELECT "email" FROM sending WHERE "login"=$1;
Also since this file contains the password to the database, only _smtp should be able to read it:
listen on all tls pki replace.with.host.name filter { check_dyndns, check_rdns, check_fcrdns, senderscore, rspamd } #listen on all port smtps smtps pki replace.with.host.name auth <auths> senders <sendermap> masquerade #listen on all port submission tls-require pki replace.with.host.name auth <auths> senders <sendermap> masquerade listen on all port smtps smtps pki replace.with.host.name auth <auths> listen on all port submission tls-require pki replace.with.host.name auth <auths>
action "receive_aliases" lmtp "/var/dovecot/lmtp" rcpt-to alias <aliases> match from local for local action "receive_aliases"
action "receive_vmail" lmtp "/var/dovecot/lmtp" rcpt-to virtual <virtuals> match from any for domain <domains> action "receive_vmail"
action "outbound" relay helo replace.with.host.name match from auth for any action "outbound"
And finally start the smtpd:
1
rcctl start smtpd
/etc/rspamd/worker-proxy.inc
In this file i actually just changed the spam_header to X-Spam-Status, but this optional.
I’ve chosen to only put in things you need to change or append, everything else should remain as is.
Why did i do this? Well since dovecot has evolved into this nice configuration-file layout, i decided that this is the most efficient way to keep this document clean and relevant.
/etc/dovecot/conf.d/10-auth.conf
Towards the beginning of the file, disable plaintext authentication:
1
disable_plaintext_auth = yes
Then at the end of the file, there are several includes. We are going to comment the auth-system.conf.ext and are going to comment in the auth-sql.conf.ext instead:
password_query = SELECT email AS user, '{CRYPT}' || password AS password FROM accounts WHERE active = true AND email = '%u' AND email != '' AND password != '' user_query = SELECT email FROM delivery WHERE email = LOWER('%u')
/etc/dovecot/dovecot.conf
Last but not least we update the protocols we are going to use:
1
protocols = imap pop3 lmtp
And finally start the dovecot:
1
rcctl start dovecot
Adding Accounts and Aliases
To generate securely hashed passwords, you can use “smtpctl encrypt” and then enter your password. The resulting hash can be used as replacement for PASSWORD:
1 2
INSERT INTO accounts (email,password) VALUES ('my@first.email.address','PASSWORD'); INSERT INTO virtuals (email,destination) VALUES ('my@second.mail.address','my@first.email.address');
That’s it
You should now be able to use this setup as expected.
If you find any errors, you can find me on Twitter and let me know!